前段时间在项目中遇到了一个奇怪的问题,遂记录一下解决过程。
现象
使用了其他部门提供的sdk进行开发,向他们的组件中注册了一个回调函数,当触发回调函数的时候,内部state一直是初始值,而当前组件的state却保持着更新。
- 使用hooks声明页码和页数的状态state
// 声明页码和页数的状态state
const [pageIndex, setPageIndex] = useState<number>(0);
const [pageCount, setPageCount] = useState<number>(0);
- 根据获取到的题目数据,设置所有页数和当前页码
getQuizApi(id).then((quiz) => {
setPageCount(quiz.pages.length || 0) // 目前为4
setPageIndex(quiz.pageIndex || 0) // 目前为0
})
- 此时通过react devtools看到组件状态为
pageIndex = 0
和pageCount = 4
- 当触发回调onMethod时,在回调函数中在取值
pageIndex
和pageCount
一直为0
const onMethod = (data: any) => {
console.log(pageData, pageCount) // 0 0
}
问题原因
sdk内部使用 useCallback 函数,而callback 内部对 state 的访问依赖于 JavaScript 函数的闭包。如果useCallback的依赖项不变,那么闭包内的state就会是上一次执行callback里的值。
解决办法
- 让sdk开发人员增加useCallback中的依赖项。
- 采用下面参考文档中的方法,使用useRef 来存放一些会发生变化的值。