web-dev-qa-db-fra.com

Actualiser l'écran précédent sur goBack ()

Je suis nouveau à React Native. Comment pouvons-nous actualiser/recharger l'écran précédent lorsque vous y revenez en appelant goBack()?

Disons que nous avons 3 écrans A, B, C:

A -> B -> C

Lorsque nous exécutons goBack() à partir de l'écran C, il retourne à l'écran B mais avec les anciens états/données. Comment pouvons-nous le rafraîchir? Le constructeur ne se fait pas appeler une seconde fois.

9
Adnan Ali

Oui, le constructeur n'est appelé que pour la première fois et vous ne pouvez pas l'appeler deux fois.

First : Mais vous pouvez séparer le getter/setter de données du constructeur et le mettre dans une fonction. Ainsi, vous pourrez passer la fonction à la scène suivante et, chaque fois que vous reviendrez, vous pourrez simplement rappeler la fonction .

Mieux : Vous pouvez créer une fonction de retour dans votre première scène, qui met également à jour la scène lors du retour et transmet la fonction de retour. Ainsi, la deuxième scène ne serait pas au courant de votre fonction de mise à jour, ce qui est raisonnable.

Best : Vous pouvez utiliser redux et envoyer une action de retour dans votre deuxième scène. Ensuite, dans votre réducteur, vous prenez soin de revenir en arrière et de rafraîchir votre scène.

0
Bat

Ajouter Api Call dans callBack résout le problème

componentDidMount() {
    this.props.fetchData();
    this.willFocusSubscription = this.props.navigation.addListener(
      'willFocus',
      () => {
        this.props.fetchData();
      }
    );
  }

  componentWillUnmount() {
    this.willFocusSubscription.remove();
  }
9
Mukundhan

Sur votre écran, le constructeur B fonctionnera comme par magie :)

    this.props.navigation.addListener(
          'didFocus',
          payload => {
            this.setState({is_updated:true});
          }
    );
2
Brijesh Singh

La fonction d'écoute intégrée fournie avec React-Navigation serait la solution la plus simple. Chaque fois qu'un composant est "concentré" sur une nouvelle fois en revenant en arrière, l'auditeur se déclenche. En écrivant une fonction loadData pouvant être appelée à la fois lors du chargement du composant ET lorsque le récepteur est averti, vous pouvez facilement recharger des données lors de la navigation précédente.

   componentWillMount(){
    this._subscribe = this.props.navigation.addListener('didFocus', () => {
     this.LoadData();
     //Put your Data loading function here instead of my this.LoadData()
    });}
2
RawBData

Malheureusement, aucune de ces réponses n'a fonctionné pour moi, mais j'ai trouvé une bibliothèque simple, elle fait le même travail

[npm install --save react-native-event-listeners][1]

componentDidMount() {
        this.listener = EventRegister.addEventListener('reloadData', (data) => {
            console.log("data is fetched");
            this.updateState(data); // private function that update the state using setState to trigger render
        });
    }

componentWillUnmount() {
    EventRegister.removeEventListener(this.listener)
}

Et dans un autre composant, dans mon cas, un bouton d'opacité:

<TouchableOpacity
            onPress={() => {
                fetch('url').then(data => {
                    ServiceLocator.saveData('matba', data);
                    EventRegister.emit('reloadData', data);
                    props.nav.goBack()
                })
                    .catch(error =>{
                        console.log(error);
                        Alert.alert("Cannot connect to the server");
                        props.nav.goBack()
                    });
            }}
        >

.... ......

0
Damian Lattenero

Si vous essayez d’obtenir de nouvelles données dans une vue précédente et que cela ne fonctionne pas, vous voudrez peut-être revenir sur la façon dont vous dirigez les données vers cette vue pour commencer. L'appel de goBack ne devrait pas affecter le montage d'un composant précédent et n'appellera probablement pas son constructeur à nouveau comme vous l'avez indiqué.

Dans un premier temps, je vous demanderais si vous utilisez un Composant , PureComponent ou Composant fonctionnel . En fonction de votre commentaire de constructeur, il semble que vous étendiez une classe de composants.

Si vous utilisez un composant, la méthode de rendu est soumise à shouldComponentUpdate et la valeur de votre état est dans votre contrôle.

Je recommanderais d'utiliser composantWillReceiveProps pour valider que le composant reçoit les nouvelles données et s'assurer que son état a été mis à jour pour refléter les nouvelles données.

Si vous utilisez le constructeur pour appeler une fonction API ou asynchrone, envisagez de déplacer cette fonction dans un composant parent de la route à partir de laquelle vous appelez goBack et du composant que vous souhaitez mettre à jour avec les données les plus récentes. . Ensuite, vous pouvez demander à votre composant parent de réinterroger l'API ou de mettre à jour son état à partir d'un composant enfant.

Si la route C met à jour "l'état/les données" de l'application, cette mise à jour doit être propagée à un parent partagé des routes A, B et C, puis transmise comme accessoire.

Vous pouvez également utiliser une solution de gestion d'état telle que Redux pour conserver cet état indépendamment des composants parent/enfant - vous encapsuleriez vos composants dans un composant connect d'ordre supérieur pour obtenir les dernières mises à jour chaque fois que l'état de l'application change.

TL; DR En fin de compte, il semble que la réponse à votre question repose sur l'emplacement de stockage de l'état de votre application. Il doit être stocké suffisamment haut dans la hiérarchie de vos composants pour que chaque route reçoive toujours les dernières données sous forme d'accessoire, transmises par son parent.

0
joel.bowen

Cette réponse suppose que la bibliothèque de navigation react-native-navigation est utilisée, ce qui est peu probable car elle ne possède pas de méthode goBack () ...

Le constructeur n'appelle pas une seconde fois car les écrans A et B sont toujours restitués (mais cachés derrière l'écran C). Si vous avez besoin de savoir quand l'écran B sera de nouveau visible, vous pouvez écouter les événements de navigation .

class ScreenB extends Component {
  constructor(props) {
    super(props);
    // Listen to all events for screen B
    this.props.navigator.setOnNavigatorEvent(this.onNavigatorEvent);
  }

  onNavigatorEvent = event => {
    switch (event.id) {
      case 'willAppear':
        // refresh your state...
        break;
  };
}

Autres événements: willDisappear, didAppear, didDisappear

Une autre solution à votre problème consiste à utiliser une solution de gestion d'état telle que Redux pour fournir l'état à tous les écrans chaque fois qu'il est mis à jour (plutôt que sur les transitions d'écran. Voir ancien exemple de réact-native-nav/redux .

0
Royce Townsend