Redux中mapStateToProps获取的props值过时,store.getState()正常
问题分析与解决方案
我一眼就看出问题出在闭包捕获旧props上,这是类组件结合异步回调(比如WebSocket订阅)时很常见的坑。
为什么会这样?
当你在stompSuccessCallBack方法里调用stompClient.subscribe时,传入的回调函数会"捕获"当前时刻的this.props——也就是组件第一次渲染时的初始props。之后,哪怕Redux状态更新导致组件重新渲染、生成了新的props,这个已经订阅好的WebSocket回调仍然持有旧props的引用,不会自动更新。而store.getState()是直接从Redux Store中读取最新状态,所以能拿到正确的值。
怎么解决?
我们需要让WebSocket回调能访问到组件的最新props,这里给你两种适合类组件的方案:
方案1:用实例变量保存最新props
在组件中维护一个实例变量,每次组件更新时同步最新的props,然后在回调里使用这个变量:
class Key extends React.Component { constructor(props) { super(props); // 初始化最新props引用 this.latestProps = props; } componentDidUpdate() { // 每次组件更新时,更新最新props的引用 this.latestProps = this.props; } stompSuccessCallBack = (frame, stompClient) => { stompClient.subscribe(KEY_READER_NODE, keyData => { // 这里改用this.latestProps获取最新状态 if (!this.latestProps.isKeyManagementWindowOpen) { this.loginWithKey(keyData.body); } else { this.addToKeyList(keyData.body); } }); } // ...其他方法 }
方案2:改用函数组件+useRef(推荐长期方案)
如果你有机会重构组件为函数组件,用useRef来保存最新props会更简洁:
import { useRef, useEffect } from 'react'; const Key = (props) => { const latestProps = useRef(props); useEffect(() => { latestProps.current = props; }, [props]); const stompSuccessCallBack = (frame, stompClient) => { stompClient.subscribe(KEY_READER_NODE, keyData => { if (!latestProps.current.isKeyManagementWindowOpen) { loginWithKey(keyData.body); } else { addToKeyList(keyData.body); } }); }; // ...其他逻辑 };
额外检查点
- 确认你的组件确实被包裹在Redux的
Provider组件内,否则connect不会生效。 - 检查是否有自定义的
shouldComponentUpdate方法阻止了组件更新,如果有的话,确保它会在isKeyManagementWindowOpen变化时返回true。
这样修改后,你就能正常通过props访问Redux的最新状态了,不用再直接调用store.getState()~
内容的提问来源于stack exchange,提问作者Claim
相关产品推荐
相关产品推荐

