如何更新filteredData状态以避免Maximum update depth exceeded警告
问题原因分析
这个错误是因为第二个useEffect依赖filteredData,但在effect内部又调用setFilteredData更新该状态——每次更新都会触发effect重新执行,形成无限循环,最终触发React的最大更新深度限制。
解决方案
方案1:合并过滤与排序逻辑到同一个Effect
把过滤和排序步骤放在同一个useEffect中,只在原始数据jobsData或过滤条件activeFilters变化时执行一次计算,避免循环触发:
const { data: jobsData, isLoading, isError, error, } = useGetJobsQuery(curCustomers.map((item) => item.id).join(",")); const [activeFilters, setActiveFilters] = useState({}); const [filteredData, setFilteredData] = useState(jobsData?.data); const filterFields = ["customer", "work_zone", "status", "employee"]; const sortFields = [ { name: "number", sortBy: "date" }, { name: "execution_date", sortBy: "date" }, { name: "auction_end", sortBy: "date" }, { name: "auction_start", sortBy: "date" }, ]; useEffect(() => { if (jobsData?.data) { // 先执行过滤 let processedData = filterData(jobsData.data, activeFilters, filterFields); // 再执行排序 processedData = sortData(processedData, activeFilters, sortFields); setFilteredData(processedData); } }, [jobsData, activeFilters]); // 仅依赖原始数据和过滤条件,切断循环链
方案2:用useMemo替代状态存储派生数据
既然filteredData是由jobsData和activeFilters计算得到的派生数据,没必要用useState存储,直接用useMemo实时计算,更符合React最佳实践:
const { data: jobsData, isLoading, isError, error, } = useGetJobsQuery(curCustomers.map((item) => item.id).join(",")); const [activeFilters, setActiveFilters] = useState({}); const filterFields = ["customer", "work_zone", "status", "employee"]; const sortFields = [ { name: "number", sortBy: "date" }, { name: "execution_date", sortBy: "date" }, { name: "auction_end", sortBy: "date" }, { name: "auction_start", sortBy: "date" }, ]; // 直接计算过滤+排序后的最终数据 const filteredAndSortedData = useMemo(() => { if (!jobsData?.data) return []; let result = filterData(jobsData.data, activeFilters, filterFields); result = sortData(result, activeFilters, sortFields); return result; }, [jobsData, activeFilters]); // 渲染时直接使用filteredAndSortedData即可
额外注意事项
- 如果
filterData或sortData是组件内部定义的函数,建议用useCallback包裹,保证函数引用稳定,避免useMemo或useEffect不必要的重复执行。 - 检查
sortData是否会返回与原数组完全相同的引用,如果是,即使内容未变化也会触发更新,这种情况可以在更新前做浅比较,只有数据真的变化时再执行setFilteredData。
内容的提问来源于stack exchange,提问作者David Abramov
相关产品推荐
相关产品推荐

