简体   繁体   中英

React conditional rendering with history

I have a parent component which maintains state for three 'form' components that render in sequence. It looks something like this:

<Parent>
    { renderFormBasedOnState() }
</Parent>

FormA renders, then when next is click FormB renders then FormC renders, all in the parent.

Previously I was using a React Router to do this, but the problem is, I don't want the user to be able to bookmark /formb or /formc, as that would be an invalid state.

I can do this with a switch statement, but then I lose forward / back button browser history ability - and I don't want to basically re-implement react-router in my component. What is the simplest way to go about this?

Haven't tried it for the back of the browser, but it could look something like this:

  export default class tmp extends React.Component {
    state = {
      currentVisibleForm: 'A'
    }

  onBackButtonEvent = (e) => {
    if(this.state.currentVisibleForm !== 'A') {
      e.preventDefault();

      //Go back to the previous visible form by changing the state
    } else {
      // Nothing to do
    }

  }

  componentDidMount = () => {
    window.onpopstate = this.onBackButtonEvent;
  }

  render() {
    return (
      <Parent>
        {this.state.currentVisibleForm === 'A' &&
          <FormA />
        }
        {this.state.currentVisibleForm === 'B' &&
          <FormB />
        }
        {this.state.currentVisibleForm === 'C' &&
          <FormC />
        }
      </Parent>
    )
  }
}

Tell me if it is of any help!

So I was able to get this working with the history api , however it may not be worth the effort to fine tune - I may revert. Managing state in two places is kind of dumb. Note this history object is the same from the application's 'Router' component, and doesn't conflict.

state = {
    FormData: {},
    action: 'Form_1'
}

componentWillMount() {
    this.unlistenHistory = history.listen((location) => {
        if (location.state) {
            this.setState(() => ({
                action: location.state.action
            }));
        }
    });
    history.push(undefined, {action: 'FORM_1'});
}

componentWillUnmount() {
    this.unlistenHistory();
}

finishForm1 = () => {
    const action = 'Form_2';
    history.push(undefined, { action });
    this.setState((prevState) => ({
        // business stuff,
        action
    }));
};


renderCurrentState() {
    switch(this.state.action) {
        case 'FORM_1': 
            return <Form1 />
        ...
    }
}

render() {
    return (
    <div>
        { this.renderCurrentState() }
    </div>
    );
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM