回调函数内state值未更新,如何获取更新后的state值?
问题解决思路
问题根源
React的状态更新是异步批量处理的,调用setCurrentMessage(message)后,currentMessage不会立刻更新为新值,所以在同一个订阅回调里直接访问currentMessage,拿到的始终是初始值,后续的currentMessage === message判断也永远不会成立。
解决方案
方案1:用useEffect监听状态变化
把触发dispatchMiddleware的逻辑放到useEffect里,当currentMessage更新后自动执行:
import { useEffect } from 'react'; // 订阅逻辑只负责更新状态 directLine.activity$ .filter((activity) => activity.type === 'message') .subscribe((message) => { setCurrentMessage(message); }); // 监听currentMessage变化,状态更新后触发dispatch useEffect(() => { if (currentMessage) { dispatchMiddleware({ payload: { message_type: 'MESSAGE', }, type: 'MWD_CONVERSATIONS_FROM_WEB_SOCKET', }); } }, [currentMessage, dispatchMiddleware]); // 依赖项确保状态变化时触发逻辑
方案2:直接使用订阅回调中的message触发dispatch
既然已经在回调里拿到了最新的message,完全不需要依赖更新后的currentMessage,直接调用dispatchMiddleware即可:
directLine.activity$ .filter((activity) => activity.type === 'message') .subscribe((message) => { setCurrentMessage(message); // 直接用当前拿到的message触发dispatch,无需等待state更新 dispatchMiddleware({ payload: { message_type: 'MESSAGE', // 需要传递message数据的话,直接在这里传入即可 message: message }, type: 'MWD_CONVERSATIONS_FROM_WEB_SOCKET', }); });
注意事项
- 使用方案1时,要确保
dispatchMiddleware加入useEffect的依赖数组,避免闭包导致的旧引用问题;如果dispatchMiddleware是稳定的(比如来自Redux的useDispatch),可以放心添加。 - 若项目使用类组件,逻辑类似:可以把
setState的回调函数作为第二个参数,在状态更新完成后执行dispatch,或者用componentDidUpdate生命周期监听状态变化。
内容的提问来源于stack exchange,提问作者Nandha Kumar
相关产品推荐
相关产品推荐

