React函数组件中无需useEffect,如何在调用处状态变更后执行函数?
React函数组件中确保状态更新后执行指定函数
在类组件里,要保证状态更新后执行函数的顺序很简单,直接用setState的回调参数即可:
setState(updater[, callback])
官方文档明确说明:setState的回调函数(无论哪种形式),都会保证在状态更新完成后触发。
但在函数组件里,如果直接像下面这样写,没法保证callFuncHere执行时var已经更新为10:
setVar(10); callFuncHere(); // 此时var的值可能还没更新
而且因为不是每次更新状态都需要执行这个函数,所以没法用useEffect来实现(useEffect会监听状态的所有变化,无法按需触发)。
下面提供两种可行的方案:
方案一:封装带Promise的状态更新函数
通过Promise封装状态更新逻辑,调用时用async/await等待状态更新完成:
import { useState, useEffect, useRef } from 'react'; function YourComponent() { const [varState, setVarState] = useState(0); const resolveRef = useRef(null); // 封装带Promise的setVar const setVar = (newValue) => { return new Promise(resolve => { resolveRef.current = resolve; setVarState(newValue); }); }; // 监听状态变化,触发resolve useEffect(() => { if (resolveRef.current) { resolveRef.current(); resolveRef.current = null; } }, [varState]); // 调用示例 const handleAction = async () => { await setVar(10); callFuncHere(); // 此时varState已确保更新为10 }; return <button onClick={handleAction}>更新状态并执行函数</button>; }
方案二:使用useReducer结合回调引用
利用useReducer的状态更新逻辑,通过ref存储回调,在状态更新后触发:
import { useReducer, useEffect, useRef } from 'react'; const reducer = (state, action) => { switch (action.type) { case 'UPDATE_VAR': return { ...state, var: action.payload.value }; default: return state; } }; function YourComponent() { const [state, dispatch] = useReducer(reducer, { var: 0 }); const callbackRef = useRef(null); // 监听var的变化,执行回调 useEffect(() => { if (callbackRef.current) { callbackRef.current(); callbackRef.current = null; } }, [state.var]); // 封装带回调的setVar const setVar = (value, callback) => { callbackRef.current = callback; dispatch({ type: 'UPDATE_VAR', payload: { value } }); }; // 调用示例 const handleAction = () => { setVar(10, callFuncHere); // 状态更新后自动执行callFuncHere }; return <button onClick={handleAction}>更新状态并执行函数</button>; }
这两种方案都能让你在调用状态更新的地方,按需决定是否执行后续函数,且100%保证函数在状态更新完成后触发。
内容的提问来源于stack exchange,提问作者mimic
相关产品推荐
相关产品推荐

