函数组件实现MVVM:不使用useSelector获取Redux更新状态值
不用useSelector实现Redux状态更新触发组件重渲染
你当前的核心问题是:直接调用store.getState()只是一次性读取当前状态,没有订阅Redux store的更新事件。而useSelector的核心作用就是帮你完成「订阅指定状态切片+状态变化时触发组件重渲染」的工作,所以去掉它之后组件无法感知状态变化。
下面是不依赖useSelector的实现方案:
方案1:手动订阅Redux Store + 组件本地状态
通过store.subscribe手动监听状态变化,结合useState和useEffect让组件感知更新:
修改你的View.js代码:
export const View = () => { const vm = useMemo(() => new ENReceivingViewModel(), []); const model = useMemo(() => new ENREceivingModel(), []); // 用本地state保存渲染所需的最新数据,初始值从store获取 const [jsonData, setJsonData] = useState(model.getData()); useEffect(() => { // 订阅store的变化:每次dispatch后执行回调 const unsubscribe = store.subscribe(() => { const latestData = model.getData(); setJsonData(latestData); }); // 组件卸载时取消订阅,避免内存泄漏 return unsubscribe; }, [model]); return ( <TextInput value={jsonData[0]} onChangeText={vm.onChangeTextHandler} /> ); }
方案2:封装成自定义Hook(复用性更强)
如果多个组件都需要这个逻辑,可以封装成自定义Hook,用法和useSelector类似:
// 自定义Hook:替代useSelector const useReduxState = (selector) => { // 初始值通过selector从store获取 const [state, setState] = useState(() => selector(store.getState())); useEffect(() => { const unsubscribe = store.subscribe(() => { // 每次store更新时,用selector获取最新状态并更新本地state setState(selector(store.getState())); }); // 清理订阅 return unsubscribe; }, [selector]); return state; }
然后在View.js中使用:
export const View = () => { const vm = useMemo(() => new ENReceivingViewModel(), []); const model = useMemo(() => new ENREceivingModel(), []); // 用自定义Hook获取状态,自动订阅更新 const jsonData = useReduxState(state => state.mReducer.jsonData); return ( <TextInput value={jsonData[0]} onChangeText={vm.onChangeTextHandler} /> ); }
关键说明
store.subscribe的回调会在每次dispatch动作执行后触发,此时我们重新获取最新状态并更新组件本地state,就能触发重渲染。- 必须在组件卸载时调用
unsubscribe,否则会导致内存泄漏。 - 自定义Hook里的
selector参数和useSelector的用法一致,可以灵活选择需要监听的状态切片。
内容的提问来源于stack exchange,提问作者Uzef Shaikh
相关产品推荐
相关产品推荐

