React useState钩子在异步函数调用中状态不更新的问题求助
React useState钩子在异步函数调用中状态不更新的问题求助
兄弟,我懂你这个坑!这其实是闭包陷阱搞的鬼,我之前也踩过一模一样的坑😅
咱们先聊聊为啥会出现这个问题:当你定义getPalettesPosition这个异步函数的时候,它会捕获当前作用域里的paletteFilters状态值。就算之后组件因为状态更新重新渲染了,这个函数里拿到的还是它创建时捕获的那个旧值——因为闭包会锁住当时的变量引用,不会自动同步最新的状态。而你在useEffect里能看到最新值,是因为useEffect的依赖数组会在paletteFilters更新后重新执行回调,它的回调是在新的作用域里,自然能拿到最新的状态。
给你几个实用的解决方案,挑适合你场景的来用:
方案一:把paletteFilters作为参数传入异步函数
每次调用函数时直接传最新的状态,这样函数里用的肯定是当前最新值,避开闭包问题:// 改造异步函数,接收当前过滤器作为参数 const getPalettesPosition = async (currentFilters) => { const response = await fetch(`${palettesUrl}?filters=${JSON.stringify(currentFilters)}`); const data = await response.json(); // 后续处理逻辑... }; // 调用的时候传入最新的paletteFilters getPalettesPosition(paletteFilters);方案二:用useRef保存最新状态的引用
如果你不想每次调用都传参数,可以用useRef来存最新的paletteFilters,因为ref的.current属性是可变的,不会被闭包锁住:import { useState, useRef, useEffect } from "react"; function MyThing() { const [paletteFilters, setPaletteFilters] = useState(/* 你的初始状态 */); // 用ref保存最新的过滤器状态 const filtersRef = useRef(paletteFilters); // 每次paletteFilters更新时,同步到ref中 useEffect(() => { filtersRef.current = paletteFilters; }, [paletteFilters]); const getPalettesPosition = async () => { // 从ref里拿最新的状态值 const currentFilters = filtersRef.current; const response = await fetch(`${palettesUrl}?filters=${JSON.stringify(currentFilters)}`); const data = await response.json(); // 后续处理逻辑... }; // 组件其他逻辑... }方案三:在useEffect里触发异步函数(依赖paletteFilters)
如果你的异步函数本来就是要在paletteFilters更新后才执行,那直接把它放进依赖这个状态的useEffect里,这样每次状态更新都会用最新值执行:useEffect(() => { const fetchPalettes = async () => { const response = await fetch(`${palettesUrl}?filters=${JSON.stringify(paletteFilters)}`); const data = await response.json(); // 处理返回的数据,比如更新其他状态... }; fetchPalettes(); }, [paletteFilters]); // 依赖数组里加上paletteFilters,确保状态更新就触发
你可以根据自己的业务场景选其中一种,我当时用的是方案二,挺顺手的~
备注:内容来源于stack exchange,提问作者TheGuy
相关产品推荐
相关产品推荐

