You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.29 17:54:06