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

React useState 设置值后没有立即生效?

2个答案

1
2

当您在React的函数组件中使用useState钩子来设置一个状态值时,您可能会注意到,调用设置状态的函数后,状态的值不会立即改变。这是因为React中的状态设置是异步的。具体来说,这意味着React将在稍后某个时间点批量处理状态更新和重新渲染组件,而不是在调用设置状态函数的时候立即更新状态和重新渲染。

这样做有几个好处:

  1. 性能优化:通过合并多个状态更新,React可以减少不必要的渲染次数,从而避免额外的性能开销。
  2. 一致性保障:这样可以确保在一个事件处理函数中,不会因为状态更新导致其他状态的计算出现不一致的情况。

请看以下例子来说明这一点:

jsx
import React, { useState } from 'react'; function Counter() { const [count, setCount] = useState(0); const handleClick = () => { // 这里尝试连续更新状态,但状态的变化不会立即反映 setCount(count + 1); setCount(count + 1); // 在这个函数调用后,你可能会期待count是2,但是实际上它仍然是0 // 因为这两次更新会被合并,且基于相同的开始状态(0)计算 }; return ( <div> <p>Count: {count}</p> <button onClick={handleClick}>Increment</button> </div> ); }

在上面的例子中,当handleClick函数被调用时,即使我们调用了两次setCount来增加count,但在这个事件处理函数结束之前,你不会看到count的值发生变化。在实践中,如果你希望连续的状态更新彼此依赖,你应该使用函数形式的setState来确保每次更新都基于最新的状态:

jsx
setCount(previousCount => previousCount + 1);

使用函数形式的更新可以确保每次更新都基于上一次更新后的状态,而不是基于状态的闭包值。

2024年6月29日 12:07 回复

React 的 useEffect 有自己的状态/生命周期。它与状态的突变有关,直到效果被破坏时才会更新状态。

只需在参数状态中传递一个参数或将其保留为黑色数组即可完美运行。

shell
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]) # or use this 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]) => { // console.log(country, project, region); setData({ countries: country, projects: project, regions: region }); }) } catch { console.log("data fetch error") } })() }, [setData]);

或者,您可以尝试 React.useRef() 在 React hook 中进行即时更改。

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

你的答案