react hooks 一出现便受到了许多开发人员的追捧
上面的hook全是闭包, 注意依赖
项目中使用很频繁的一个场景定义一个useState
const [baseState, setBaseState] = useState<IBaseState>({
searchData: {
activity: dateContext.activity,
sort_column: null,
sort_direction: null,
area: '仅看员工'
},
pagination: {
current: 1,
pageSize: 10,
total: 0
},
})
然后在请求接口后改变pagination的total值,但是接口请求时间是不确定的,searchData的值可能已经发生变化了
try {
const res = await getMarkeyActivityBooking({
...filterObjectNull({
activity: baseState.searchData.activity,
area: baseState.searchData.area,
sort_column: baseState.searchData.sort_column,
sort_direction: baseState.searchData.sort_direction,
page_index: baseState.pagination.current,
page_size: baseState.pagination.pageSize
})
})
setBaseState({
searchData: baseState.searchData, // <-- searchData的值可能已经发生变化了
pagination: {
...baseState.pagination,
total: res.total
}
})
} catch (err) {
console.log(err)
}
setState之后会触发useEffect导致重复调用接口,造成递归
useEffect(() => {
fetchData()
}, [
baseState.searchData.activity, // <-- 依赖可能发生变化
baseState.searchData.sort_column, // <-- 依赖可能发生变化
baseState.searchData.sort_direction, // <-- 依赖可能发生变化
baseState.searchData.area, // <-- 依赖可能发生变化
baseState.pagination.current,
baseState.pagination.pageSize
])
解决方法
setBaseState((prev: IBaseState) => ({
searchData: prev.searchData,
pagination: {
...prev.pagination,
total: res.total
}
}))