首页 > 解决方案 > MobX:观察到的组件在可观察到的变化后不会重新渲染

问题描述

我在 React Native 中有一个基本的 MobX 设置,但是我的组件在 observable 更新后没有重新渲染,我似乎不知道为什么。

反应原生0.56.1;反应16.4.1 ; 暴徒4.5.0 ; mobx 反应5.2.8

店铺

class AppStore {
  drawer = false;
  toggleDrawer = () => {
    this.drawer = !this.drawer;
  }
}
decorate(AppStore, {
  drawer: observable,
  toggleDrawer: action
});

const app = new AppStore();
export default app;

零件

class _AppLayout extends React.Component {
  constructor(props) {
    super(props);

    this.state = {
      drawerAnimation: new Animated.Value(0)
    };
  }

  UNSAFE_componentWillReceiveProps(nextProps) {
    console.log('will not get called');
    if (this.props.app.drawer !== nextProps.app.drawer) {
      Animated.timing(this.state.drawerAnimation, {
        toValue: nextProps.app.drawer === true ? 1 : 0,
        duration: 500
      }).start();
    }
  }

  render() {
    console.log("will only be called on first render");
    const translateX = this.state.drawerAnimation.interpolate({
      inputRange: [0, 1],
      outputRange: [0, -(width - 50)]
    });

    return (
      <Animated.View style={[styles.app, { transform: [{ translateX }] }]}>
        <View style={styles.appContent}>
          <RouterSwitch />
        </View>
        <View style={styles.appDrawer} />
      </Animated.View>
    );
  }
}
const AppLayout = inject("app")(observer(_AppLayout));

触发器(来自不同的组件)

<TouchableOpacity
  onPress={() => {
    app.toggleDrawer();
    // will reflect the new value
    console.log(app.drawer)
  }}
  style={styles.toggle}
/>

编辑:经过一番调查,没有触发重新渲染,因为我没有在render()方法中使用商店,只在componentWillReceiveProps. 这对我来说似乎很奇怪?

当我在渲染中使用存储时,即使只是分配一个变量,它也会开始工作:

const x = this.props.app.drawer === false ? "false" : "true";

标签: javascriptreactjsreact-nativemobxmobx-react

解决方案


根据 mobx 文档,

观察者函数/装饰器可用于将 ReactJS 组件转换为反应式组件。它将组件的渲染函数包装在 mobx.autorun 中,以确保在渲染组件期间使用的任何数据都会在更改时强制重新渲染。它可以通过单独的 mobx-react 包获得。

所以你需要使用this.props.app.drawer观察者组件的内部渲染函数来接收来自 mobx 的反应。

有关 mobx 如何以及何时做出反应的更多详细信息,请参阅此链接。


推荐阅读