Search code examples
formsreactjsreact-nativereactjs-flux

Form Fails to Reset Upon Submission ReactJS Flux


I am attempting to reset the state of a component upon submitting form data in ReactJS. Aside from the fact that the form fails to clear, I suspect that if I do manage to successfully reset it, the data being rendered in the child component will disappear once I do.

What I want to happen is, upon form submission, render data passed to child component, clear and reset form, but leave child component with original data rendered. Then, upon next submission, re-render child component according to new data passed.

Here is my code:

class Badge extends React.Component {
  constructor(props) {
    super(props)
        this.state = {}
    }

   componentDidMount() {
        fetch('https://api.github.com/users/' + this.props.user)
        .then(data => data.json())
        .then(data => {
            this.setState({
            userData: data
          })
        })
     }

    render() {
        if (!this.state.userData) return <p>Loading...</p> 
        return (
      <div>
        <h4>{this.state.userData.name}</h4>
      </div>
       )
    }
} 

class Search extends React.Component {
    constructor(props) {
        super(props)
      this.state = {user: '', clicked: false}

    this.handleChange= this.handleChange.bind(this);
    this.handleSubmit= this.handleSubmit.bind(this);
    this.resetForm= this.resetForm.bind(this); 
    }  

    resetForm() {
    this.setState({user: '', clicked: false})
  } 

   handleChange(event) {
      this.setState({ user: event.target.value })
    } 

   handleSubmit(event) {
    this.setState({ clicked: true }) 
    alert(this.state.user + ' was submitted'); 
    {this.resetForm}
    event.preventDefault(); 
    }

    renderUserInfo() {
       return <Badge user={this.state.user} />
        }

    render() {
    return (
        <div>
        <p>Current User: {this.state.user}</p>
          <h2>
            Find a Github User
          </h2>
        <form onSubmit={this.handleSubmit}>
          <label>
            Username: 
            <input type="text" user={this.state.user} onChange={this.handleChange} />
          </label>
          <input type="submit" value="Submit" />
        </form>
       {this.state.clicked && this.renderUserInfo()}
      </div>
      )
  }
}

Solution

  • Since you don't want the component to re-render everytime after the first one(only when the user submits), I am using a variable called sendData. Also used componentWillReceiveProps for new props from the parent.

    class Badge extends React.Component {
    
      constructor(props) {
        super(props)
        this.state = {}
      }
      componentWillReceiveProps(nextProps){
    
        if(nextProps.sendData) {
          this.setState({
            userData: ''
          });
          fetch('https://api.github.com/users/' + nextProps.user)
          .then(data => data.json())
          .then(data => {
            this.setState({
              userData: data
            });
    

    The data refresh happens from the child component by passing the function form parent component.

            this.props.resetForm();
          })
        }
      }
      componentDidMount() {
          fetch('https://api.github.com/users/' + this.props.user)
            .then(data => data.json())
            .then(data => {
              this.setState({
                userData: data
              });
              this.props.resetForm();
            })
    
      }
    
      render() {
        if (!this.state.userData) return <p>Loading...</p>
    
        return (
          <div>
            <h4>{this.state.userData.name}</h4>
          </div>
        )
      }
    }
    
    class Search extends React.Component {
      constructor(props) {
        super(props)
        this.state = { user: '', clicked: false, sendData: false, }
    
        this.handleChange = this.handleChange.bind(this);
        this.handleSubmit = this.handleSubmit.bind(this);
        this.resetForm = this.resetForm.bind(this);
      }
    
      resetForm() {
        this.setState({ user: '', sendData: false })
      }
    
      handleChange(event) {
        this.setState({ user: event.target.value })
      }
    
      handleSubmit(event) {
        this.setState({ clicked: true, sendData: true })
        alert(this.state.user + ' was submitted');
        event.preventDefault();
      }
    
      renderUserInfo() { 
    

    Passing the required data to the child component. return }

      render() {
        return (
          <div>
            <p>Current User: {this.state.user}</p>
            <h2>
              Find a Github User
              </h2>
            <form onSubmit={this.handleSubmit}>
              <label>
                Username:
                <input type="text" user={this.state.user} value={this.state.user} onChange={this.handleChange} />
              </label>
              <input type="submit" value="Submit" />
            </form>
            {this.state.clicked && this.renderUserInfo()}
          </div>
        )
      }
    }