简体   繁体   中英

How to set 2 states asynchronously in React using useState

I have this function:

const [numbers, setNumbers] = useState([]);
const [rows, setRows] = useState([]);

const addRow = () => {
    setNumbers([...numbers, numbers.length+1]);
    setRows([...rows,
        <NewGradeRow key={numbers[numbers.length-1]} number={numbers[numbers.length-1]}/>]);
}

that is supposed to add new rows. It should be adding a new value to the numbers hook, then using the new value in the numbers hook to add a new row in the rows hook. It runs synchronously though and the new row doesn't use the new value given to the numbers hook. How would I fix this?

Take the new values from the calculation performed (one plus the length of the original numbers ), rather from the numbers variable (which hasn't updated yet):

const addRow = () => {
    const newNum = numbers.length + 1;
    setNumbers([...numbers, newNum]);
    setRows([...rows,
        <NewGradeRow
          key={newNum}
          number={newNum}
        />
    ]);
};

You could also use useEffect to watch for changes to numbers . Remove the setRows from addRow , and do:

useEffect(() => {
    const newNum = numbers[numbers.length - 1];
    setRows([...rows,
        <NewGradeRow
          key={newNum}
          number={newNum}
        />
    ]);
}, numbers.length);

(if the length of numbers can change from other sources as well, you'll have to factor that into the logic)

You have some misunderstanding here. First, setNumbers and setRows actually run asynchronous , in a sense that they are batched together to change state only once and not individually run and change app state twice. Read this question to understand this issue.

Second, you cannot get the "updated" value of the state immediately. This has somethings to do with closure. Read this question or this article to understand more about this problem. This issue apply for both callback and hooks

is " NewGradeRow " a jsx component?? if so i doubt it could be called or stated in setRows state instaed it should be seperated from the setRows state and put in the return statement.

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