React useState的两种赋值办法区别?
感谢各位朋友进来观看,哪怕只是了解并未解惑。若闲代码多,小弟也可以略微解释一下。主要的问题就是:setPage后,useEffect能监听到page发生了变化。可在loadData函数内部使用时,拿到的还是未更改时的page值。
下面是具体代码:
import { useState, useEffect } from 'react'
export default function () {
const [page, setPage] = useState({ current: 1, pageSize: 10 });
function loadData() {
console.log({ current: page.current })
}
useEffect(() => {
console.log('发生了改变', page)
}, [page])
function onClick() {
setPage((pre) => ({ ...pre, current: pre.current + 1 }))
setTimeout(() => {
console.log('加载数据时', page)
loadData()
}, 1000)
}
return <>
<div>
<p>测试页面</p>
<button onClick={onClick}>添加</button>
</div>
</>
}
感谢各位朋友能完整的看完代码,若有看法或者其他都可以说出来,谢谢各位
回复
1个回答

test
2024-07-07
问题原因:函数组件里通过 useState
获取的 page
和 loadData
里的 page
形成一个闭包。点击按钮后,函数组件重新执行,此时 useState
返回的了一个新的 page
,注意区分这个新 page
不是之前形成闭包的旧 page
,而 loadData
里 page
绑定的是旧的 page
,所以你拿到的是未更改的值。
解决方案:将 setTimeout
这种带有副作用的函数放在 useEffect
中处理:
import { useState, useEffect } from "react";
export default function App() {
const [page, setPage] = useState({ current: 1, pageSize: 10 });
function loadData() {
console.log({ current: page.current });
}
useEffect(() => {
console.log("发生了改变", page);
}, [page]);
// 带有副作用的函数放在 useEffect 处理
useEffect(() => {
const id = setTimeout(() => {
console.log("加载数据时", page);
loadData();
}, 1000);
return () => clearTimeout(id);
}, [page]);
function onClick() {
setPage((pre) => ({ ...pre, current: pre.current + 1 }));
// setTimeout(() => {
// console.log("加载数据时", page);
// loadData();
// }, 1000);
}
return (
<>
<div>
<p>测试页面</p>
<button onClick={onClick}>添加</button>
</div>
</>
);
}
这是 React 的经典闭包问题,回答的比较简略,希望对你有所帮助。
回复

适合作为回答的
- 经过验证的有效解决办法
- 自己的经验指引,对解决问题有帮助
- 遵循 Markdown 语法排版,代码语义正确
不该作为回答的
- 询问内容细节或回复楼层
- 与题目无关的内容
- “赞”“顶”“同问”“看手册”“解决了没”等毫无意义的内容