如何用autorun监听React Navigation当前导航参数变化?
嘿,我来帮你搞定用MobX的autorun监听React Navigation导航参数变化的问题!
问题根源
你当前的代码没法正常触发监听,核心原因是React Navigation的navigation.state.params本身不是MobX的可观察对象,MobX没法自动追踪它的变化。另外你的代码里还存在一个小拼写错误(currParam...应该是currParams),这也会导致日志输出异常。
解决方案思路
我们需要把导航参数同步到一个MobX可观察的变量中,然后让autorun依赖这个可观察变量,这样参数变化时就能自动触发监听逻辑了。具体步骤如下:
- 用
@observable定义一个变量存储当前导航参数 - 订阅React Navigation的
state事件,参数变化时同步更新这个可观察变量 - 让
autorun依赖这个可观察变量,实现监听 - 记得在组件卸载时清理监听,避免内存泄漏
完整修正代码
import { observer, observable, autorun } from 'mobx-react'; import React, { Component } from 'react'; import { View, Text } from 'react-native'; // 建议定义更具体的导航类型,这里用any做简化 type PropsType = { navigation: any; }; @observer export default class TestScreen extends Component<PropsType> { // 用MobX可观察变量存储导航参数 @observable currentParams = this.props.navigation.state.params || {}; // 存储导航监听器和autorun的清理函数 private navigationListener: any; private autorunDisposer: (() => void) | undefined; constructor(props: PropsType) { super(props); // 模拟1.5秒后更新导航参数 setTimeout(() => { props.navigation.setParams({ a: 'b' }); }, 1500); // 用autorun监听可观察参数的变化 this.autorunDisposer = autorun(() => { console.log('currParams', this.currentParams); console.log('a', this.currentParams?.a); // 修复了拼写错误 }); } componentDidMount() { // 订阅导航state变化事件,同步更新可观察参数 this.navigationListener = this.props.navigation.addListener('state', () => { // 解构参数生成新对象,确保MobX能检测到变化 this.currentParams = { ...this.props.navigation.state.params } || {}; }); } componentWillUnmount() { // 清理导航监听器 this.navigationListener?.remove(); // 清理autorun,避免内存泄漏 this.autorunDisposer?.(); } render() { return ( <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}> <Text>当前a参数值:{this.currentParams.a}</Text> </View> ); } }
额外优化建议
如果你只想在参数真正变化时触发逻辑,也可以用reaction代替autorun,它会更精准:
import { reaction } from 'mobx'; // 在constructor里替换autorun为reaction this.reactionDisposer = reaction( () => this.currentParams, // 追踪的数据源 (params) => { // 数据源变化时执行的逻辑 console.log('参数发生变化:', params); console.log('a的值:', params?.a); } ); // 同样在componentWillUnmount里清理 this.reactionDisposer?.();
内容的提问来源于stack exchange,提问作者lironer
相关产品推荐
相关产品推荐

