简体   繁体   中英

React hook useState method updates array unexpectedly

I am learning React hook and tried to update an array value. What I want to achieve is when the button is clicked, the name and the counter of the first element perform the +1 operation. However, the code performs the operation twice instead. So the button shows

Initial : Click 0 FirstArgument

Click 1 : Click 1 FirstArgument1

Click 2 : Click 3 FirstArgument111

Click 3 : Click 5 FirstArgument11111

...

Here is the code snipe:

import React, { useState } from "react";

function HookCount() {
  const initState = [
    {
      counter: 0,
      name: "FirstArgument",
    },
    "SecondArgument",
  ];

  const [variable, setCount] = useState(initState);

  const setStateFun = () => {
    setCount((prevVariable) => {
      let updateList = [...variable];
      updateList[0].name = prevVariable[0].name + 1;
      updateList[0].counter = prevVariable[0].counter + 1;
      updateList[1] = prevVariable[1];
      return updateList;
    });
  };

  return (
    <div>
      <button onClick={setStateFun}>
        Click {variable[0].counter} {variable[0].name}
      </button>
    </div>
  );
}

export default HookCount;

The questions that I have are:

  1. Why the code behaves like that. What I did wrong or what is the proper way to achieve this.

  2. If I replace let updateList = [...variable]; with let updateList = prevVariable; the state does not change anymore. Why can't we use prevVariable instead of spread the array here?

I don't see setCount or variable defined anywhere it your code, so I cannot guess how you implemented them. However, setStateFun is just overcomplicated.

By using the functional setState , you already have access to prevVariable . To perform the increment, it can be simplified like so:

import React, { useState } from "react";
import "./styles.css";

export default function App() {
  const [variable, setCount] = useState([
    {
      counter: 0,
      name: "FirstArgument"
    },
    "SecondArgument"
  ]);

  const setStateFun = () => {
    setCount(prevVariable => [
      {
        counter: prevVariable[0].counter + 1,
        name: prevVariable[0].name + 1
      },
      prevVariable[1]
    ]);
  };

  return (
    <div>
      <button onClick={setStateFun}>
        Click {variable[0].counter} {variable[0].name}
      </button>
    </div>
  );
}

See it here:

编辑 nameless-pine-4hsbj

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM