React父组件函数无法首次获取子组件更新的state值问题咨询
问题根源
这是React函数组件典型的闭包陷阱问题:saveNewNote函数在首次渲染时就捕获了当前作用域下的savedSearchName初始值(空字符串),后续savedSearchName状态更新后,saveNewNote没有重新生成,仍然引用旧闭包中的旧值,所以第一次点击时读取到空字符串,第二次点击时函数才会读取到更新后的状态值。
可行解决方法
方案1:用useCallback绑定状态依赖
给saveNewNote包裹useCallback,并把savedSearchName加入依赖项,状态更新后函数会自动重新生成,读取最新值:
const saveNewNote = useCallback(async (agent: Agent, agentsMode: AgentsMode): Promise<void> => { console.log(savedSearchName); // 可正常读取最新值 // 原有业务逻辑 }, [savedSearchName]); // 必须把用到的状态加入依赖
如果saveNewNote需要传给子组件,建议子组件搭配React.memo使用,避免不必要的重渲染。
方案2:用useRef同步最新状态
如果你不想调整函数依赖,可以新增ref同步savedSearchName的最新值,函数内直接读取ref的值即可:
const [savedSearchName, setSavedSearchName] = useState(''); // 新增ref同步状态 const savedSearchNameRef = useRef(savedSearchName); useEffect(() => { savedSearchNameRef.current = savedSearchName; }, [savedSearchName]);
修改saveNewNote的取值逻辑:
const saveNewNote = async (agent: Agent, agentsMode: AgentsMode): Promise<void> => { console.log(savedSearchNameRef.current); // 永远读取最新的状态值 // 原有业务逻辑 }
方案3:点击时直接传参
如果表格点击的业务逻辑中可以直接获取到savedSearchName的值,可以直接把该值作为参数传给saveNewNote,避开闭包问题。
内容的提问来源于stack exchange,提问作者BluePilot
相关产品推荐
相关产品推荐

