乐闻世界logo
搜索文章和话题

The useState set method is not reflecting a change immediately

2个答案

1
2

When using the useState hook in a React function component to set a state value, you might observe that the state does not update immediately after calling the state-setting function. This is because React handles state updates asynchronously. Specifically, React batches state updates and re-renders the component at a later time, rather than updating the state and re-rendering immediately upon calling the state-setting function.

This approach offers several benefits:

  1. Performance Optimization: React batches multiple state updates to minimize unnecessary re-renders, reducing performance overhead.
  2. Consistency Guarantee: This ensures that within an event handler, state updates do not lead to inconsistencies in calculations for other states.

Consider the following example to illustrate this:

jsx
import React, { useState } from 'react'; function Counter() { const [count, setCount] = useState(0); const handleClick = () => { // Attempting to update the state consecutively, but the state does not change immediately setCount(count + 1); setCount(count + 1); // After this function call, you might expect count to be 2, but it remains 0 // Because these two updates are batched and calculated based on the same initial state (0) }; return ( <div> <p>Count: {count}</p> <button onClick={handleClick}>Increment</button> </div> ); }

In the above example, when the handleClick function is invoked, even if setCount is called twice to increment count, the value of count does not change until after the event handler completes. In practice, if you need consecutive state updates to depend on each other, use the functional form of setState to ensure each update is based on the latest state:

jsx
setCount(previousCount => previousCount + 1);

Using the functional form ensures that each update is based on the latest state, not the closure value of the state.

2024年6月29日 12:07 回复

React's useEffect has its own lifecycle. State mutations within it are asynchronous, and state updates are not immediate; they are batched and applied after the effect completes.

Simply pass a single dependency or keep it as an empty array for it to work perfectly.

javascript
React.useEffect(() => { console.log("effect"); (async () => { try { let result = await fetch("/query/countries"); const res = await result.json(); let result1 = await fetch("/query/projects"); const res1 = await result1.json(); let result11 = await fetch("/query/regions"); const res11 = await result11.json(); setData({ countries: res, projects: res1, regions: res11 }); } catch {} })(data) }, [setData])

Alternatively, you can use this:

javascript
useEffect(() => { (async () => { try { await Promise.all([ fetch("/query/countries").then((response) => response.json()), fetch("/query/projects").then((response) => response.json()), fetch("/query/regions").then((response) => response.json()) ]).then(([country, project, region]) => { setData({ countries: country, projects: project, regions: region }); }) } catch { console.log("data fetch error") } })() }, [setData]);

Alternatively, you can try using React.useRef() for immediate changes within React hooks.

javascript
const movies = React.useRef(null); useEffect(() => { movies.current = 'values'; console.log(movies.current) }, [])
2024年6月29日 12:07 回复

你的答案