Search code examples
javascriptreactjsradio-buttonreact-forms

Why do the radio buttons show the value of the previous page and not render unselected


If I select a radio button on the first page and click on "Next", the "same" radio button on the second page is also selected. Why?

I tried to narrow down the example below to the very essential.

I want to keep the pages separated. Furthermore, I also tried to use useForm, but the core problem remains the same.

const Example = () => {
  const [page, setPage] = React.useState(1);
  if (page === 1) {
    return (
      <>
        <div>page1</div>
        <input type="radio" name="options1" id="option1_1" value="1" />
        <input type="radio" name="options1" id="option1_2" value="2" />
        <input type="radio" name="options1" id="option1_3" value="3" />
        <button onClick={() => setPage(page - 1)}>back</button>
        <button onClick={() => setPage(page + 1)}>next</button>
      </>
    );
  } else {
    return (
      <>
        <div>page2</div>
        <input type="radio" name="options2" id="option2_1" value="1" />
        <input type="radio" name="options2" id="option2_2" value="2" />
        <input type="radio" name="options2" id="option2_3" value="3" />
        <input type="radio" name="options2" id="option2_4" value="4" />
        <button onClick={() => setPage(page - 1)}>back</button>
        <button onClick={() => setPage(page + 1)}>next</button>
      </>
    );
  }
};

Code Sandbox of the example above


Solution

  • I don't like this solution. But it is at least a feasible solution. I wrap the form in an additional <div> on every even page so that React recognizes that there is a change on the page.

    This is the new code

    import * as React from "react";
    import { useForm } from "react-hook-form";
    
    export default function App() {
      const [page, setPage] = React.useState(1);
      const { register } = useForm();
    
      if (page === 1) {
        return (
          <>
            <div>page1</div>
            <input
              type="radio"
              name="options1"
              id="option1_1"
              {...register("q1")}
              value="1"
            />
            <input
              type="radio"
              name="options1"
              id="option1_2"
              {...register("q1")}
              value="2"
            />
            <input
              type="radio"
              name="options1"
              id="option1_3"
              {...register("q1")}
              value="3"
            />
    
            <button onClick={() => setPage(page + 1)}>next</button>
          </>
        );
      } else {
        return (
          <>
            <div>page2</div>
            <div>
              <input
                type="radio"
                name="options2"
                id="option2_1"
                {...register("q2")}
                value="1"
              />
              <input
                type="radio"
                name="options2"
                id="option2_2"
                {...register("q2")}
                value="2"
              />
              <input
                type="radio"
                name="options2"
                id="option2_3"
                {...register("q2")}
                value="3"
              />
              <input
                type="radio"
                name="options2"
                id="option2_4"
                {...register("q2")}
                value="4"
              />
    
              <button onClick={() => setPage(page - 1)}>back</button>
            </div>
          </>
        );
      }
    }
    

    Here is the new Sandbox link.