2 votes

MobX: Le composant observé ne se rerender pas après un changement observable

J'ai une configuration de base de MobX dans React Native, mais mon composant ne se réaffiche pas après la mise à jour d'un observable et je ne parviens pas à comprendre pourquoi.

react-native 0.56.1; react 16.4.1; mobx 4.5.0; mobx-react 5.2.8

Store

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

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

Component

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

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

  UNSAFE_componentWillReceiveProps(nextProps) {
    console.log('ne sera pas appelé');
    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("ne sera appelé qu'au premier rendu");
    const translateX = this.state.drawerAnimation.interpolate({
      inputRange: [0, 1],
      outputRange: [0, -(width - 50)]
    });

    return (

    );
  }
}
const AppLayout = inject("app")(observer(_AppLayout));

Trigger (à partir d'un composant différent)

 {
    app.toggleDrawer();
    // reflétera la nouvelle valeur
    console.log(app.drawer)
  }}
  style={styles.toggle}
/>

MODIFICATION : Après quelques recherches, aucun réaffichage n'était déclenché car je n'utilisais pas le store dans la méthode render(), seulement dans componentWillReceiveProps. Cela me paraît super étrange ?

Lorsque j'utilise le store dans le rendu, même en affectant simplement une variable, cela fonctionne :

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

5voto

Anantha kumar Points 306

Conformément à la documentation de mobx,

La fonction / décorateur observer peut être utilisée pour transformer les composants ReactJS en composants réactifs. Elle enveloppe la fonction de rendu du composant dans mobx.autorun pour s'assurer que toutes les données utilisées lors du rendu d'un composant forcent une réexécution en cas de modification. Elle est disponible via le package mobx-react séparé.

Vous devez donc utiliser this.props.app.drawer à l'intérieur de la fonction de rendu du composant observer pour recevoir les réactions de mobx.

Référez-vous à ce lien pour plus de détails sur la manière dont et quand mobx réagit.

1voto

Tareq El-Masri Points 1076

Vous devez utiliser observer de mobx-react sur votre composant, il est également recommandé d'utiliser des décorateurs. Assurez-vous également d'utiliser Provider sur votre composant Racine

Store

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

Composant

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('ne sera pas appelé');
    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("ne sera appelé qu'au premier rendu");
    const translateX = this.state.drawerAnimation.interpolate({
      inputRange: [0, 1],
      outputRange: [0, -(width - 50)]
    });

    return (

    );
  }
}

Événement

 {
    app.toggleDrawer();
    // reflétera la nouvelle valeur
    console.log(app.drawer)
  }}
  style={styles.toggle}
/>

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X