React自定义Hook的useEffect中如何正确更新多个state状态
报错根因
你的代码错误和「在useEffect中更新多个state」无关,本质是变量引用错误:pageNumber是你通过useState声明的数字类型状态,初始值为0,不存在data属性。你需要的总页数totalPages存放在接口返回的响应对象里,应该从axios请求返回的结果对象中读取。
另外你原代码中将请求返回的参数命名为data,和你自己声明的data状态重名,非常容易导致混淆写错,建议修改参数名区分。
修复后的代码
import axios from 'axios'; import { useEffect, useState } from 'react'; const useList = (url) => { const [data, setData] = useState([]); const [pageNumber, setPageNumber] = useState(0); // 额外添加加载、错误状态,可按需选择是否保留 const [loading, setLoading] = useState(true); const [error, setError] = useState(null); useEffect(() => { // 添加取消请求逻辑,避免组件卸载后仍更新状态导致内存泄漏 const source = axios.CancelToken.source(); const fetchData = async () => { try { const res = await axios.get(url, { cancelToken: source.token }); // 同一作用域下连续更新多个状态完全合法,React会自动批量处理 setData(res.data.content); setPageNumber(res.data.totalPages); setError(null); } catch (err) { if (!axios.isCancel(err)) { setError(err); setData([]); setPageNumber(0); } } finally { setLoading(false); } }; fetchData(); // 组件卸载时主动取消未完成的请求 return () => source.cancel(); }, [url]); return { data, pageNumber, loading, error }; } export default useList;
补充说明
React完全支持在同一个useEffect、同一个异步回调里连续调用多个setXxx方法更新多个状态,框架会自动批量处理更新,不会触发多次不必要的重渲染,你原来的写法逻辑是可行的,只是变量取值写错了而已。
内容的提问来源于stack exchange,提问作者Stone
相关产品推荐
相关产品推荐

