Skip to content

Instantly share code, notes, and snippets.

@joe-oli
Created August 28, 2024 10:50
Show Gist options
  • Save joe-oli/7b2195aaac101cdee80ec43429a786b9 to your computer and use it in GitHub Desktop.
Save joe-oli/7b2195aaac101cdee80ec43429a786b9 to your computer and use it in GitHub Desktop.
Wizard or multi-step interface

Designing a multi-step wizard interface in React can be approached in a few different ways. Here are two common techniques:

1. Using react-router for Each Page

Pros:

  • URL Management: Each step has its own URL, making it easier to bookmark or share specific steps.
  • State Persistence: Refreshing the page will keep you on the same step.

Cons:

  • Complexity: Requires setting up routes for each step.
  • State Management: You need to manage state across different routes, which can be complex.

Implementation:

import { BrowserRouter as Router, Route, Switch, useHistory } from 'react-router-dom';

const Step1 = () => {
  const history = useHistory();
  return (
    <div>
      <h1>Step 1</h1>
      <button onClick={() => history.push('/step2')}>Next</button>
    </div>
  );
};

const Step2 = () => {
  const history = useHistory();
  return (
    <div>
      <h1>Step 2</h1>
      <button onClick={() => history.push('/step1')}>Back</button>
      <button onClick={() => history.push('/step3')}>Next</button>
    </div>
  );
};

const Step3 = () => {
  const history = useHistory();
  return (
    <div>
      <h1>Step 3</h1>
      <button onClick={() => history.push('/step2')}>Back</button>
      <button onClick={() => alert('Submit')}>Submit</button>
    </div>
  );
};

const App = () => (
  <Router>
    <Switch>
      <Route path="/step1" component={Step1} />
      <Route path="/step2" component={Step2} />
      <Route path="/step3" component={Step3} />
      <Route path="/" component={Step1} />
    </Switch>
  </Router>
);

2. Using State to Manage Steps (Single URL)

Pros:

  • Simplicity: Easier to manage state within a single component.
  • Control: More control over the flow and state management.

Cons:

  • URL Management: Refreshing the page will reset to the first step unless you use local storage or another method to persist state.

Implementation:

import { useState } from 'react';

const Wizard = () => {
  const [step, setStep] = useState(1);

  const nextStep = () => setStep(prev => prev + 1);
  const prevStep = () => setStep(prev => prev - 1);

  return (
    <div>
      {step === 1 && (
        <div>
          <h1>Step 1</h1>
          <button onClick={nextStep}>Next</button>
        </div>
      )}
      {step === 2 && (
        <div>
          <h1>Step 2</h1>
          <button onClick={prevStep}>Back</button>
          <button onClick={nextStep}>Next</button>
        </div>
      )}
      {step === 3 && (
        <div>
          <h1>Step 3</h1>
          <button onClick={prevStep}>Back</button>
          <button onClick={() => alert('Submit')}>Submit</button>
        </div>
      )}
    </div>
  );
};

const App = () => <Wizard />;

Which is Preferable?

  • Use react-router if you need each step to be accessible via a unique URL, which is useful for deep linking and bookmarking.
  • Use State Management if you prefer a simpler setup and don't need each step to have its own URL.

Both approaches have their merits, so it ultimately depends on your specific requirements and preferences.

//using state management
import { useState } from 'react';
const Wizard = () => {
const [step, setStep] = useState(1);
const nextStep = () => setStep(prev => prev + 1);
const prevStep = () => setStep(prev => prev - 1);
return (
<div>
{step === 1 && (
<div>
<h1>Step 1</h1>
<button onClick={nextStep}>Next</button>
</div>
)}
{step === 2 && (
<div>
<h1>Step 2</h1>
<button onClick={prevStep}>Back</button>
<button onClick={nextStep}>Next</button>
</div>
)}
{step === 3 && (
<div>
<h1>Step 3</h1>
<button onClick={prevStep}>Back</button>
<button onClick={() => alert('Submit')}>Submit</button>
</div>
)}
</div>
);
};
const App = () => <Wizard />;
//using react-router
import { BrowserRouter as Router, Route, Switch, useHistory } from 'react-router-dom';
const Step1 = () => {
const history = useHistory();
return (
<div>
<h1>Step 1</h1>
<button onClick={() => history.push('/step2')}>Next</button>
</div>
);
};
const Step2 = () => {
const history = useHistory();
return (
<div>
<h1>Step 2</h1>
<button onClick={() => history.push('/step1')}>Back</button>
<button onClick={() => history.push('/step3')}>Next</button>
</div>
);
};
const Step3 = () => {
const history = useHistory();
return (
<div>
<h1>Step 3</h1>
<button onClick={() => history.push('/step2')}>Back</button>
<button onClick={() => alert('Submit')}>Submit</button>
</div>
);
};
const App = () => (
<Router>
<Switch>
<Route path="/step1" component={Step1} />
<Route path="/step2" component={Step2} />
<Route path="/step3" component={Step3} />
<Route path="/" component={Step1} />
</Switch>
</Router>
);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment