0

I am having an issue getting a third component to show up using REACT.

I am trying to change the state of workflow, and show Component Three, but I am not sure what I am doing wrong.

After clicking on the continue button, the state changes.

Workflow is changed to WELCOME_MSG, the switch below works.

But I can't seem to return this Component "ComponentThree"

case 'WELCOME_MSG': return ();

class ComponentOne extends React.Component {
  constructor(props) {
    super(props)
    this.state = {
      workflow: 'GET_NAME'
    }

    this.setWorkflow = this.setWorkflow.bind(this);
  }

  setWorkflow() {


    switch(this.state.workflow){
      case 'GET_NAME':
        return (<ComponentTwo/>);
      case 'WELCOME_MSG':
        return (<ComponentThree name={this.state.name} />);
    }

  }

  render() {

    console.log('ComponentOne: ',this.state.workflow );

    return this.setWorkflow();
    /*
      switch(this.state.workflow){
        case 'GET_NAME':
          return (<ComponentTwo/>);
        case 'WELCOME_MSG':
          return (<ComponentThree name={this.state.name} />);
      } */
  }
}

// showThree()



class ComponentTwo extends React.Component {
  constructor(props){
    super(props)
    this.state = {
      workflow: 'GET_NAME',
      name: 'Chris'
    }
    this.handleChange = this.handleChange.bind(this);
    this.handleClick = this.handleClick.bind(this);
    this.setWorkflow = this.setWorkflow.bind(this);
  }

  handleChange(e) {
    //this.setState({name: event.target.name});
    e.persist();



    console.log('handleChange event.target.name:', e.target);


    this.setState((prevState, props) => {
      return {
        name: e.target.value,
        workflow: 'WELCOME_MSG',
      }
    })

    /*
          this.setState(state => ({
          //name: this.state.name,
          name: e.target.value,
          //name: "sadfasdf",
        })); */





  }

  setWorkflow() {


    console.log("setWorkflow", this.state.workflow);
    switch(this.state.workflow){
      case 'GET_NAME':
        return (<ComponentTwo/>);
      case 'WELCOME_MSG':
        return (<ComponentThree />);

    }

    // name={this.state.name}
  }

  handleClick(e) {
    //console.log(this.state);

    //e.preventDefault();

    console.log('BEFORE handleClick this STATE ON CLICK :', this.state.workflow);

    console.log('this.state.name:', this.state.name);


    this.setState((prevState, props) => {
      return {
        workflow: 'WELCOME_MSG',
        name: this.state.name,
      }
    })

    return this.setWorkflow();

    //this.setWorkflow = this.setWorkflow.bind(this);
    /*      this.setState(state => ({
              //name: this.state.name,
              name: this.state.name,
              workflow: 'WELCOME_MSG'
            })); */

    console.log('ON CLICK AFTER SET STATE:', this.state);


    //return (<ComponentThree name={this.state.name} />);


    // e.preventDefault();
  }

  render() {
    //console.log('this is:', this);
    // onChange={this.handleChange}
    return (
      <div>
        <h1>Enter your name</h1>
          <div className="grid20 md-grid100">
            <input type="text" name="fname" value={this.state.name} onChange={this.handleChange} />
          </div>
          <div className="grid80 md-grid100">
            <button onClick={this.handleClick} >Continue</button>
          </div>

      </div>
    )
  }
}

class ComponentThree extends React.Component {
  render() {

    console.log('ComponentThree this is:', this);

    return (
      <div className="test">
        <h1>Hello {this.state.name}</h1>

        <h2>sfasfdadf</h2>
      </div>
    )
  }
}
ReactDOM.render(<ComponentOne />, document.querySelector("#app"))

JS Fiddle Below

https://jsfiddle.net/ameshkin/cvg2rjzo/32/

Legacy
  • 21
  • 3
  • 1
    Does this answer your question? [setState doesn't update the state immediately](https://stackoverflow.com/questions/41278385/setstate-doesnt-update-the-state-immediately) – Alexander Staroselsky Feb 25 '20 at 21:15
  • `setState()` is asynchronous. You are currently depending on the value changing immediately. `setState()` has a callback in which you can perform an action after state has been updated. – Alexander Staroselsky Feb 25 '20 at 21:17

2 Answers2

0

The state variable to show ComponentTwo or Three is in ComponentOne, but you are updating the state in ComponentTwo, and not updating the state in ComponentOne. To update the state in ComponentOne, you need to pass a function from One to Two in the props.

Edit: Here's a working fiddle https://jsfiddle.net/j5gxovdm/

Basically having the state in one place, instead of spread across all components (keeping a single source of truth)


    return (
        this.state.workflow == 'GET_NAME' 
        ? <ComponentTwo 
            setWorkflow={this.setWorkflow.bind(this)}  
            onChange={(e) => this.setState({name: e.target.value})}
            name={this.state.name}
          /> 
        : <ComponentThree name={this.state.name} />
    ) 
JorgeObregon
  • 3,020
  • 1
  • 12
  • 12
0

ComponentTwo has its own state and that state is updated upon clicking the button, not the ComponentOne state. As ComponentOne is a container component to switch ComponentTwo and ComponentThree, you have to pass the ComponentOne state as props for ComponentTwo and ComponentThree.

JS Fiddle Below

https://jsfiddle.net/richard929/g0b4d3ur/1/