web-dev-qa-db-fra.com

React: pourquoi le composant enfant ne se met pas à jour lorsque l'hôte change

Pourquoi, dans l'exemple de pseudo-code suivant, Child ne rend pas de nouveau le rendu lorsque Container change foo.bar? 

Container {
  handleEvent() {
    this.props.foo.bar = 123
  },

  render() {
    return <Child bar={this.props.foo.bar} />
}

Child {
  render() {
    return <div>{this.props.bar}</div>
  }
}

Même si j'appelle forceUpdate() après avoir modifié la valeur dans le conteneur, Child affiche toujours l'ancienne valeur.

50
Tuomas Toivonen

Parce que les enfants ne se rendent pas si les accessoires du parent changent, mais si son état change :)

Voici ce que vous montrez: https://facebook.github.io/react/tips/communicate-between-components.html

Il transmettra les données du parent à l'enfant via des accessoires, mais il n'y a pas de logique de restitution.

Vous devez définir un état sur le parent, puis le rendre à l'enfant sur l'état de changement du parent .Cela pourrait aider. https://facebook.github.io/react/tips/expose-component-functions.html

46
François Richard

Selon la philosophie de React, le composant ne peut pas changer ses accessoires. ils doivent être reçus du parent et doivent être immuables. Seul le parent peut changer les accessoires de ses enfants.

Belle explication sur état vs accessoires

aussi, lisez ce fil Pourquoi je ne peux pas mettre à jour les accessoires dans react.js?

7
Sujan Thakare

Vous devriez utiliser la fonction setState.

Container {
    handleEvent= () => { // use arrow function
        //this.props.foo.bar = 123
        //You should use setState to set value like this:
        this.setState({foo: {bar: 123}});
    };

    render() {
        return <Child bar={this.state.foo.bar} />
    }
    Child {
        render() {
            return <div>{this.props.bar}</div>
        }
    }
}

Votre code semble ne pas être valide. Je ne peux pas tester ce code.

5
JamesYin

Mettez à jour l'enfant pour que l'attribut 'clé' soit égal à nom:

Child {
  render() {
    return <div key={this.props.bar}>{this.props.bar}</div>
  }
}
3
PolinaC

Utilisez la fonction setState . Donc vous pourriez faire

       this.setState({this.state.foo.bar:123}) 

à l'intérieur de la méthode de l'événement handle.

Une fois que l'état est mis à jour, les modifications sont déclenchées et le rendu est effectué.

3
Indraneel Bende

Vous devriez probablement faire de l'enfant un composant fonctionnel s'il ne conserve aucun état, restitue simplement les accessoires, puis appelle-le depuis le parent. Une alternative à cela est que vous pouvez utiliser des points d'ancrage avec le composant fonctionnel (useState), ce qui entraînera le rendu du composant sans état.

Aussi, vous ne devriez pas modifier les propas car ils sont immuables. Maintenir l'état du composant.

Child = ({bar}) => (bar);
0
satyam soni

J'ai eu le même problème… .. C'est ma solution, je ne suis pas sûr que ce soit la bonne pratique, dites-moi sinon

state = {
  value: this.props.value
};

componentDidUpdate(prevProps) {
  if(prevProps.value !== this.props.value) {
    this.setState({value: this.props.value});
  }
}
0
petrichor