React+Redux Toolkit中dispatch后如何立即获取useState更新值
React+Redux Toolkit中useState更新后无法立即获取新值的解决方法
问题背景
使用React和Redux Toolkit开发时,调用useState的set函数后立即引用更新值,得到的却是更新前的值,已知useState更新为非同步操作。
核心需求
下拉框变更事件中重新获取地址列表后,立即根据更新后的列表长度(multipleList.length)执行判断逻辑。
现有代码
组件核心逻辑
const [ multipleList, setMultipleList ] = useState<selectAddressList[]>([]) const selAddressList = useSelectAddressList(); // ★1 监听Redux中地址列表变更,同步到本地state useEffect(() => { const setNewSelAddrList = () => { if (selAddressList && selAddressList.length > 0){ const newList = [...selAddressList] // 已确认此处存储了更新后的地址列表 setMultipleList(newList); } } setNewSelAddrList(); }, [selAddressList]) // 下拉框变更事件 const onChangeAddr3 = async(rowData:string) => { // rowData为邮政编码 if (rowData != ''){ // 根据邮政编码获取地址列表 await dispatch(fetchAsyncSelectedAddressList(rowData.toString())) // ★2 // ★希望根据更新后的地址列表数量进行判断★ if (multipleList.length == 0){ // 此处逻辑无法触发,因为multipleList还是旧值 } } };
Redux相关代码
export function useSelectAddressList():selectAddressList[] { return useSelector((state:RootState) => state.selectAddressList.list); } export const fetchAsyncSelectedAddressList = createAsyncThunk<selectAddressList[], string>( "address/list", async (zipNo : string) => { const res = await axios.get<selectAddressList[]>(`${url}xxxx/xxx`,{ params: { zipNo: zipNo, } as searchParams }); return res.data; } );
页面渲染代码
<StyleFrom> <NativeSelect required disabled = {disableAddress} value = { add3Value } onChange = {e => onChangeAddr3(e.target.value as string)} > <option key={0} value=''>{''}</option> { addr3List? addr3List.map((row) => { return ( <option key={row.zipNo} value={String(row.zipNo)}> {row.addrC} </option> ) }) : <option key={-1} value={0}>{'Failed'}</option>} </NativeSelect> </StyleFrom>
补充说明
- ★1:
selAddressList由Redux的fetchAsyncSelectedAddressList更新,当它变更时触发useEffect,将值同步到本地multipleList - ★2:通过Redux异步Thunk从API获取地址数据,更新Redux中的地址列表
尝试过在onChangeAddr3中新建数组等操作,仍无法获取更新后的列表,寻求解决方法。
解决方案
方案1:直接使用Redux中的selAddressList替代本地state
既然multipleList只是selAddressList的同步副本,完全可以直接在判断逻辑中使用selAddressList,不需要维护本地state,避免异步同步带来的不一致:
修改onChangeAddr3:
const onChangeAddr3 = async(rowData:string) => { if (rowData != ''){ await dispatch(fetchAsyncSelectedAddressList(rowData.toString())) // 直接用Redux中的最新值判断 if (selAddressList.length == 0){ // 执行你的业务逻辑 } } };
同时可删除本地的multipleList和对应的useEffect,减少冗余状态。
方案2:利用useEffect监听multipleList的变化
如果必须保留本地multipleList,可新增useEffect专门监听其更新,在状态变更后执行判断逻辑:
// 新增useEffect监听multipleList更新 useEffect(() => { if (multipleList.length === 0) { // 此处执行你的判断逻辑 } }, [multipleList]); // 修改onChangeAddr3,只负责触发数据获取 const onChangeAddr3 = async(rowData:string) => { if (rowData != ''){ await dispatch(fetchAsyncSelectedAddressList(rowData.toString())) } };
方案3:直接获取异步Thunk的返回值
createAsyncThunk的dispatch调用会返回Promise,resolve的值就是Thunk中return的结果,可直接用该返回值做判断,无需等待React/Redux状态更新:
const onChangeAddr3 = async(rowData:string) => { if (rowData != ''){ // 获取Thunk返回的最新地址列表 const newAddressList = await dispatch(fetchAsyncSelectedAddressList(rowData.toString())).unwrap(); // 直接用返回值执行判断 if (newAddressList.length == 0){ // 执行你的业务逻辑 } } };
该方法最直接,能第一时间拿到最新数据。
内容的提问来源于stack exchange,提问作者Tatsuya
相关产品推荐
相关产品推荐

