MobX: наблюдаемый компонент не перерисовывается после наблюдаемого изменения - PullRequest
0 голосов
/ 15 октября 2018

У меня есть базовая настройка MobX в React Native, но мой компонент не рендерится после обновления наблюдаемой, и я не могу понять, почему.

реакция-нативная 0,56.1 ;реагировать 16.4.1 ;mobx 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";

Ответы [ 2 ]

0 голосов
/ 15 октября 2018

В соответствии с документами mobx,

Функция наблюдателя / декоратор может использоваться для превращения компонентов ReactJS в реактивные компоненты.Он оборачивает функцию рендеринга компонента в mobx.autorun, чтобы убедиться, что любые данные, используемые во время рендеринга компонента, вызывают повторный рендеринг при изменении.Он доступен через отдельный пакет mobx-реагировать.

Таким образом, вам нужно использовать внутреннюю функцию визуализации this.props.app.drawer компонента-наблюдателя для получения реакций от mobx.

См. эта ссылка для получения более подробной информации о том, как и когда реагирует mobx.

0 голосов
/ 15 октября 2018

Вам нужно использовать observer из mobx-react в вашем компоненте, также рекомендуется использовать декораторы.Также убедитесь, что вы используете Provider на своем корневом компоненте

Store

class AppStore {
  @observable drawer = false;
  @action toggleDrawer = () => {
    this.drawer = !this.drawer;
    console.log(this.drawer)
  }
}

Компонент

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

@observer 
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 (
      <Provider app={app}>
        <Animated.View style={[styles.app, { transform: [{ translateX }] }]}>
          <View style={styles.appContent}>
            <RouterSwitch />
          </View>
          <View style={styles.appDrawer} />
        </Animated.View>
      </Provider>
    );
  }
}

Триггер

<TouchableOpacity
  onPress={() => {
    app.toggleDrawer();
    // will reflect the new value
    console.log(app.drawer)
  }}
  style={styles.toggle}
/>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...