简体   繁体   中英

React hooks useCallback not reflecting updated state

I have a simplified version of my problem as follows:

const Component = () => {
  const [data, setData] = useState([]);

  const fn = useCallback((num) => {
    const newData = [...data];
    newData.push(num);

    setData(newData);
  }, [data]);

  return <button onClick={() => fn(Math.random())}>{data.join()}</button>;
};

My problem is that newData is always [] , instead of reflecting the updated state values. Therefore, my button will only show the latest data value instead of an array with increasing values. Why is this the case as I've included it in the dependency array of the useCallback function?

Your code works just as you expect:

https://codesandbox.io/s/relaxed-ishizaka-n2eg6?file=/src/App.js

It does show the updated state values.

I guess the problem is most probably happen in the "button" component which you have simplified in your question therefore we cannot see the real problem.

There could be multiple reasons why states in the "useCallback" is not updated:

  1. you didn't add the state in the dependency of "useCallback". This is not your case as you already add data in the dependency

  2. you use this "fn" in another "useCallback" and you didn't add fn as a dependency of that "useCallback".

     // what you probably write in the "button" component const handleClick = useCallback(() => { ... doSomethingWithState(someState); props.onClick(); //<--- this is the fn you passed }, [someState]); // what you should write const handleClick = useCallback(() => { ... doSomethingWithState(someState); props.onClick(); //<--- this is the fn you passed }, [someState, props.onClick]); //<---- you need to add the method as dependency as well

please verify if this is your case.

I have a simplified version of my problem as follows:

const Component = () => {
  const [data, setData] = useState([]);

  const fn = useCallback((num) => {
    const newData = [...data];
    newData.push(num);

    setData(newData);
  }, [data]);

  return <button onClick={() => fn(Math.random())}>{data.join()}</button>;
};

My problem is that newData is always [] , instead of reflecting the updated state values. Therefore, my button will only show the latest data value instead of an array with increasing values. Why is this the case as I've included it in the dependency array of the useCallback function?

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