1

I'm working to build a multistep form flow where the user first loads: /welcome, which should then take the user through the following

step 0: `/welcome` (Should redirect to step 1)
step 1: `/welcome/workplace`
step 2: `/welcome/profile`

Here is what I have so far:

App.jsx:

import Welcome from '../containers/welcome/Welcome';

const App = ({store}) => {
  return (
    <StoreProvider store={store}>
      <ConnectedRouter history={history}>
        <Switch>
          <PrivateRoute exact path="/welcome" layout={MainLayout} component={Welcome} />
          <WithMainLayout exact path="/" component={Home} />
          <AuthRoutes path={`/${clientResourceName}`} wrapper={WithMainLayout} />
          <WithMainLayout component={NotFound} />
        </Switch>
      </ConnectedRouter>
    </StoreProvider>
  );
};

Welcome.js

import React from 'react';
import WorkPlacePage from '../../components/welcome/WorkPlacePage';

class Welcome extends React.Component {

  constructor(props) {
    super(props);
    this.state = {
      step: 1
    };
  }

  showStep() {
    const {history} = this.props

    console.log('showStep');
    console.log({history})

    switch (this.state.step) {
      case 1:
        return <WorkPlacePage history={history} />
      default:
        return (
          <div>
            <h1>Case: Default</h1>
          </div>
        );
    }
  }

  render() {
    var style = {
      width : (this.state.step / 4 * 100) + '%'
    }
    return (
      <main>
        <span className="progress-step">Step {this.state.step}</span>
        <progress className="progress" style={style}></progress>
        {this.showStep()}
      </main>
    )
  }
}

export default Welcome;

WorkPlacePage.js

import React from 'react';
import {connect} from 'react-redux';
import {bindActionCreators} from 'redux';

class WorkPlacePage extends React.Component {

  render() {

    console.log('this.props.history')
    console.log(this.props.history)

    return (
      <div>
        <h1>Workplace</h1>
        <span>
        survey things
        <button onClick={() => this.props.history.push("/confirmation")}>next page</button>
        </span>
      </div>
    );
  }
}

export default WorkPlacePage;

As a React and Redux newbie, I could use advice on the following:

  1. Am I structuring this multi-step form correctly?
  2. If a user loads /welcome in their browser, what is the right way to auto-redirect the browser to step 1 /welcome/workplace
  3. On WorkplacePage.js, I'm getting the following JS error when I click the NEXT button: =Uncaught TypeError: Cannot read property 'push' of undefined --- Why is history not defined?
halfer
  • 19,824
  • 17
  • 99
  • 186
AnApprentice
  • 108,152
  • 195
  • 629
  • 1,012

1 Answers1

1
  1. yes sure this structure looks ok. I think you'll want to create a separate route component for each step because i'm sure that each step will grow with more rules and validations.

  2. To redirect you can render <Redirect to="/somewhere/else"/> - https://github.com/ReactTraining/react-router/blob/master/packages/react-router/docs/api/Redirect.md

  3. you need to pass props into the <WorkPlacePage />

something like:

class Welcome extends React.Component {

  constructor(props) {
    super(props);
    this.state = {
      step: 1
    };
  }

  render() {
    const {history} = this.props
    switch (this.state.step) {
      case 1:
        return <WorkPlacePage history={history} />
      case 2:
        return (
          <div>
            <h1>WIP</h1>
          </div>
        );
      default:
        return (
          <div>
            <h1>Case: Default</h1>
          </div>
        );
        }

  }
}
Blair Anderson
  • 19,463
  • 8
  • 77
  • 114