title: React-Router: How do I add a new component and route to the onboarding steps on a wizard?
body: <p>This project I am working with has an onboarding Wizard, basically some code to deal with the step by step onboarding process almost similar to what you see here:</p>
  
  <p><a href="https://medium.com/@l_e/writing-a-wizard-in-react-8dafbce6db07" rel="nofollow noreferrer">https://medium.com/@l_e/writing-a-wizard-in-react-8dafbce6db07</a></p>
  
  <p>except this one supposedly has a function to convert a component or step into a route:</p>
  
  <pre><code>convertStepToRoute = step =&gt; {
      const Component = StepComponents[step.component || ''];
  
      return Component
        ? &lt;Route
            key={step.key}
            path={`${WizardLayout.pathname}/${step.url}`}
            render={this.renderRouteComponent(Component)}
          /&gt;
        : null;
    };
  </code></pre>
  
  <p><code>StepComponents</code> comes from <code>import StepComponents from '../Steps';</code> which is a directory with all the components, they were six now seven of them that are supposed to walk the user through the onboarding process.</p>
  
  <p>And its my understanding that they are pulled from the <code>index.js</code> file inside of <code>Steps/</code> directory similar to how there would be a root reducer file in a reducers folder to export all of them, the steps component in this case like so:</p>
  
  <pre><code>import glamorous from "glamorous";
  import ThemedCard from "../../ThemedCard";
  import BusinessAddress from "./BusinessAddress";
  import CreatePassword from "./CreatePassword";
  import GetInvolved from "./GetInvolved";
  import Representatives from "./Representatives";
  import Topics from "./Topics";
  import MemberBenefits from "./MemberBenefits";
  
  export const StepHeader = glamorous.div({
    marginBottom: 20,
    marginTop: 20,
    fontSize: "2rem",
    color: "#757575"
  });
  
  const OnboardingCompleted = glamorous(ThemedCard)({
    textAlign: "center",
    boxShadow: "none !important"
  });
  
  export default {
    CreatePassword,
    BusinessAddress,
    Completed: OnboardingCompleted,
    GetInvolved,
    MemberBenefits,
    Topics,
    Representatives
  };
  </code></pre>
  
  <p>Well, I added mine <code>MemberBenefits</code> and it does not seem to work, its not rendering with its corresponding route. Where could it not be registering this new step or component?</p>
  
  <p>Okay so the magic is not happening inside of <code>Onboarding/OnBoardingWizard/index.js</code>, its happening inside of <code>Wizard/WizardEngine.js</code>:</p>
  
  <pre><code>import React from "react";
  import PropTypes from "prop-types";
  import objectToArray from "../../../../common/utils/object-to-array";
  
  // TODO: figure out how to use this without making children of wizard engine tied to wizardStep
  // eslint-disable-next-line no-unused-vars
  class WizardStep {
    constructor({ component, color, order, render }, stepComponents) {
      if (!component || !render) {
        throw new Error("Component or render must be provided.");
      }
  
      let componentValue;
      if (component) {
        componentValue = this.resolveComponent(component, stepComponents);
        if (!!componentValue &amp;&amp; !React.isValidElement(componentValue)) {
          throw new Error(
            "wizard step expected component to be a valid react element"
          );
        }
      } else if (render &amp;&amp; typeof render === "function") {
        throw new Error("wizard step expected render to be a function");
      }
  
      this.Component = componentValue;
      this.color = color;
      this.order = order;
      this.render = render;
    }
  
    resolveComponent = (component, stepComponents) =&gt; {
      const componentValue = component;
  
      if (typeof component === "string") {
        const componentValue = stepComponents[component];
        if (!componentValue) {
          throw new Error("component doesnt exist");
        }
      }
  
      return componentValue;
    };
  }
  
  export default class WizardEngine extends React.Component {
    static propTypes = {
      steps: PropTypes.oneOfType([PropTypes.object, PropTypes.array]),
      initActiveIndex: PropTypes.oneOfType([PropTypes.func, PropTypes.number]),
      stepComponents: PropTypes.object
    };
  
    constructor(props) {
      super(props);
      this.state = {
        activeIndex: this.resolveInitActiveIndex(props),
        steps: this.buildStepsFromConfig(props)
      };
    }
  
    componentWillReceiveProps(nextProps) {
      this.setState({ steps: this.buildStepsFromConfig(nextProps) });
    }
  
    resolveInitActiveIndex = props =&gt; {
      const { initActiveIndex } = props;
      let activeIndex = 0;
  
      if (typeof initActiveIndex === "function") {
        activeIndex = initActiveIndex(props);
      }
  
      if (typeof initActiveIndex === "number") {
        activeIndex = initActiveIndex;
      }
  
      return activeIndex;
    };
  
    buildStepsFromConfig = props =&gt; {
      const { steps } = props;
      let stepArr = steps;
  
      // validate stepList
      if (typeof steps === "object" &amp;&amp; !Array.isArray(steps)) {
        stepArr = objectToArray(steps);
      }
  
      if (!Array.isArray(stepArr)) {
        throw new Error(
          `Unsupported Parameter: Wizard Engine(steps) expected either (object, array); got ${typeof stepArr}`
        );
      }
  
      return stepArr;
  
      // return stepArr.map(step =&gt; new WizardStep(step));
    };
  
    setActiveIndex = activeIndex =&gt; {
      this.setState({ activeIndex });
    };
  
    goForward = () =&gt; {
      this.setState(prevState =&gt; ({
        activeIndex: prevState.activeIndex + 1
      }));
    };
  
    goBack = () =&gt; {
      this.setState(prevState =&gt; ({
        activeIndex: prevState.activeIndex - 1
      }));
    };
  
    render() {
      const { children } = this.props;
      const childProps = {
        ...this.state,
        setActiveIndex: this.setActiveIndex,
        goForward: this.goForward,
        goBack: this.goBack,
        currentStep: this.state.steps[this.state.activeIndex]
      };
  
      if (Array.isArray(children)) {
        return (
          &lt;div&gt;
            {children.map((child, i) =&gt; {
              if (typeof child === "function") {
                return child(childProps);
              }
              childProps.key = `${child.type.name}_${i}`;
              return React.cloneElement(child, childProps);
            })}
          &lt;/div&gt;
        );
      }
  
      if (typeof children === "function") {
        return children(childProps);
      }
  
      return children;
    }
  }
  </code></pre>