someone
someone

Reputation: 691

How to keep already chosen value in ReactJS

I have following code.

What I'm trying to do is, in the first step, select one of the elements, store it in my state, and in the last step, console.log all my data. Also, the user can go from the last step to the first and change what he chose before. But the problem is that I can't save what the user selects for the first time.

For example, if the user selects the second one, and then on the last step they go back, then the first one is displayed as selected. How can I fix this?

here is my code

App.js

     const [current, setCurrent] = useState(0);
      const [data, setData] = useState({
        firstName: "AAA",
        lastName: "BBB",
        age: 26
      });
      const steps = [
        {
       content: (
        <PackageChoose setCurrent={setCurrent} data={data} setData={setData} />
        ),
        id: 0
       },
       {
        content: <LastStep setCurrent={setCurrent} data={data} />,
        id: 1
       }
     ];
     return (
       <div className="App">
        <div>{steps[current].content}</div>
      </div>
     );

packageChoose (or first step)

   const PackageChoose = ({ setCurrent, data, setData }) => {
     const [selected, setSelected] = useState(1);
     const [packageType, setPackageType] = useState(data.package || "choice");
     return (
        <div>
          <div
            onClick={() => {
            setPackageType("choice");
            setData({ ...data, packageType: packageType });
          }}
         >
           <SelectCard
             id={1}
             selected={selected}
             onSelect={setSelected}
             text="text 1"
          />
        </div>
        <div
          onClick={() => {
            setPackageType("select");
           setData({ ...data, packageType: packageType });
          }}
        >
         <SelectCard
           id={2}
          selected={selected}
          onSelect={setSelected}
          text="text 2"
        />
        </div>
        <button onClick={() => setCurrent(1)}>Next</button>
      </div>
     );
   };

Last step

    const LastStep = ({ setCurrent, data }) => {
    return (
       <div>
         LastStep
         <button
           onClick={() => {
             setCurrent(0);
           }}
         >
           Previous
         </button>
         <button onClick={() => console.log("data===>", data)}> submit </button>
       </div>
     );
    };

Selected Card reusable component

   const SelectCard = ({ id, selected, onSelect, text }) => {
     const myClassName =
        id === selected
          ? Styles.selectCardWrapperActives
          : Styles.selectCardWrapper;

      return (
        <div className={classNames(myClassName)} onClick={() => onSelect(id)}>
          <div> {text} </div>
        </div>
      );
    };

Please help me to fix this problem.

Upvotes: 1

Views: 64

Answers (2)

Shan
Shan

Reputation: 1568

You need to update the packageType inside onClick handler. Since setState calls are batched and enqueued inside event handler and state updates may be asynchronous. You can't access the packageType state immediately after setting it.

PackageChoose.js

Card 1

onClick={() => setData({ ...data, packageType: "choice" })}

Card 2

onClick={() => setData({ ...data, packageType: "select" })}

set the packageType directly on data.

Upvotes: 0

Amila Senadheera
Amila Senadheera

Reputation: 13245

You can move the selected state in PackageChoose to App level.

  1. In App.js define the selected state and pass as props.
export default function App() {
  const [selected, setSelected] = useState(1);
  ...
  ...

        <PackageChoose
          ...
          ...
          selected={selected}
          setSelected={setSelected}
        />
}
  1. In PackageChoose use the props passed above and remove the local selected state.
const PackageChoose = ({ setCurrent, data, setData, setSelected, selected }) => {

Edit hopeful-violet-zsv35

Upvotes: 1

Related Questions