Mettre à jour les composants créés dynamiques

Colin

Situation

J'ai un composant parent qui rend certains composants enfants. Le composant enfant doit afficher les informations transmises par le composant parent.

Le contexte

Un jeu de cuirassé multijoueur:

Le composant parent contient un champ de 10 x 10 à 10 x 30 boutons (composants enfants). Si un bouton est enfoncé, un signal avec la position du bouton est émis vers l'API. L'API décide si le bouton enfoncé doit changer sa couleur.


Problème

En mettant à jour l'état du parent, les accessoires des composants enfants ne seront pas mis à jour si l'enfant est créé dynamiquement.


Tentatives de solution

Ne pas rendre Childs dynamiquement:

Pas possible dans mon cas

Utiliser redux

Je considère l'enfant comme un composant de vidage / présentation car il n'affiche que des informations. Dans mon cas également, il y a entre 100 et 300 composants enfants. Redux et React

Utiliser des références

Il y a entre 100 et 300 composants enfants ... Ne pas abuser des références


Question

Que devrais-je faire? Existe-t-il une solution qui n'est pas anti-modèle?

Code actuel

class Parent extends React.Component {
  constructor(props) {
    super(props);
    this.state={
      foo: 'BAR'
    }
    this.child=undefined;
  }
  
  componentWillMount(){
    this.child=<Child foo={this.state.foo}/>
  }  
  
  componentDidMount(){
    var that=this
    setTimeout(function(){ 
      that.setState({  //it is just here for demonstration
        foo: 'FOO'
      }) 
    }, 1000);
  }
  
  render() {
    return (
      <div>
       Is: {this.child}
       Not Dynamic created: <Child foo={this.state.foo}/>
       Actual: <p>{this.state.foo}</p>
      </div>
    );
  }
}

class Child extends React.Component {
  render() {
    return (
      <p>{this.props.foo}</p>
    );
  }
}

ReactDOM.render(<Parent />, document.getElementById('app'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="app"></div>

Code avec l'approche de @RaghavGarg et @Clinton Blackburn

class Parent extends React.Component {
  constructor(props) {
    super(props);
    this.state={
      foo: 'BAR'
    }
    this.child=undefined;
  }
  
  componentDidMount(){
    var that=this
    setTimeout(function(){ 
      that.setState({  //it is just here for demonstration
        foo: 'FOO'
      }) 
    }, 1000);
  }
  
  renderChild(){
    return <Child foo={this.state.foo} />
  }
  
  render() {
    const child=this.renderChild()
    return (
      <div>
       Is: {child}
       Not Dynamic created: <Child foo={this.state.foo}/>
       Actual: <p>{this.state.foo}</p>
      </div>
    );
  }
}

class Child extends React.Component {
  render() {
    return (
      <p>{this.props.foo}</p>
    );
  }
}

ReactDOM.render(<Parent />, document.getElementById('app'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id='app'/>

Garg Raghav

Comme @Clinton l'a dit, componentWillMountne serait appelé qu'une seule fois. Donc, vous lancez essentiellement votre this.childvariable, mais ne mettez à jour que l'état, vous devez également mettre à jour la valeur de la variable.

Puisque vous créez simplement vos composants dynamiques et que vous les enregistrez dans l'instance de classe (comme this.child). Je vous recommande de faire la même tâche dans componentWillUpdate. Ainsi, chaque fois que votre état change, il sera reflété dans vos variables dépendantes. Mais assurez-vous de ne pas utiliser setStatecette méthode de cycle de vie.

componentWillUpdate()est appelée juste avant le rendu lorsque de nouveaux accessoires ou état sont reçus. Utilisez cette opportunité pour effectuer une préparation avant qu'une mise à jour ne se produise.

Envisagez également d'utiliser le constructeur pour initier l'état et de ne pas l'utiliser setStatedans componentWillMount.

componentWillMount()est appelé juste avant le montage. Il est appelé avant render(), donc un appel setState()synchrone dans cette méthode ne déclenchera pas de rendu supplémentaire. En règle générale, nous vous recommandons d'utiliser constructor()plutôt le pour initialiser l'état.

Référence:

https://reactjs.org/docs/react-component.html#unsafe_componentwillupdate https://reactjs.org/docs/react-component.html#unsafe_componentwillmount

Mettre à jour après l'ajout du contexte

Alors maintenant, je suppose que vous aurez un DS (peut-être un objet ou un tableau imbriqué) dans l'état dans lequel vous maintiendrez le statut de chaque boîte (composant enfant). Vous pouvez faire une boucle dessus et fournir un unique key(peut-être comme {row}-{col}) à chacun d'eux, il vous suffit maintenant de mettre à jour l'état afin de refléter le changement dans l'enfant spécifique.

Remarque: l' utilisation de la clé unique pour chaque enfant permettra à react d'optimiser en interne le nouveau rendu et ne rendra pas l'enfant (en utilisant une clé unique), ce qui n'est pas modifié. Voir le code ci-dessous pour référence.

this.state = {
  boxes: {
    1: { 
      1:{ status: true, /* more data */ },
      2:{ status: true, /* more data */ },
    },
    2: { 
      1:{ status: true, /* more data */ },
      2:{ status: true, /* more data */ },
    },
    3: { 
      1:{ status: true, /* more data */ },
      2:{ status: true, /* more data */ },
    },
    4: { 
      1:{ status: true, /* more data */ },
      2:{ status: true, /* more data */ },
    }
  }
};

// this will create a 4x2 box, now you will render using above object

// ...somewhere in your render method
{
  Object.keys(this.state.boxes).map(row => (
    <div key={`row-${row}`} className="row">
      {
        Object.keys(this.state.boxes[row]).map(column => (
          <Child 
            key={`box-${row}x${column}`} 
            data={this.state.boxes[row][column]} 
          />
        ))
      }
    </div>
  ))
}

Désormais, chaque fois que vous changez la case statusof say 2x1en false, react ne restituera que l'enfant avec la clé box-2x1.

Mettre à jour après le commentaire OP

shouldComponentUpdatedoit être utilisé pour décider si vous souhaitez mettre à jour le composant lorsque l'état change. C'est une méthode de cycle de vie du composant React. Par défaut, il retourne true, mais vous pouvez revenir en falsefonction de votre condition pour ne pas mettre à jour le composant. Cela aiderait certainement à maintenir les bonnes performances.

Référence: React: le composant Parent restitue tous les enfants, même ceux qui n'ont pas changé lors du changement d'état

Cet article est collecté sur Internet, veuillez indiquer la source lors de la réimpression.

En cas d'infraction, veuillez [email protected] Supprimer.

modifier le
0

laisse moi dire quelques mots

0commentaires
connexionAprès avoir participé à la revue

Articles connexes

Mettre à jour les composants créés dynamiques

Comment mettre à jour les composants créés dans un JSX.Element?

Mettre à jour les éléments dynamiques

Mettre à jour tous les composants React children

Mettre à jour les options de sélection avec les données dynamiques données

Comment mettre à jour les propriétés individuelles des objets dans les états des composants React?

Comment mettre à jour les données entre les composants?

Limiter Redux pour mettre à jour uniquement les composants affectés par le changement

Comment mettre à jour les données des composants après avoir appelé la fonction montée?

Livewire: impossible de mettre à jour les composants enfants après l'ajout d'un nouvel enregistrement

lorsque de nouveaux accessoires sont passés, mettre à jour les états des composants fonctionnels

Inno Setup: mettre à jour la taille requise après avoir décoché les composants par programme

Mettre à jour les composants après en avoir supprimé un de Firebase

Mettre à jour les champs dynamiques dans OTRS via SOAP

Comment mettre à jour les propriétés dynamiques dans les littéraux d'objets auto-référencés?

react-redux peut mettre à jour les composants intelligents enfants sans mettre à jour les parents?

Mettre à jour correctement les composants de la balançoire?

Comment mettre à jour correctement les composants de la bibliothèque

Comment mettre à jour dynamiquement les styles de composants angulaires

Mettre à jour Vue Router sans remonter les composants?

Mettre à jour UI Framework CSS pour les nouveaux composants Web

Modifier / mettre à jour les composants FXML dans une autre classe

JavaScript, mettre à jour l'objet avec des clés dynamiques

Comment mettre à jour mongodb avec plusieurs clés dynamiques?

Mettre à jour les valeurs dans un objet json en fonction des clés dynamiques disponibles sous forme de tableau

React lazy composants non chargés sur les routes dynamiques

Angular - émettre un événement du composant parent vers les composants enfants dynamiques

Mettre à jour l'état désactivé des composants dynamiques en fonction de la valeur de l'état Vuex

Pandas Dataframe -mettre à jour les lignes et les colonnes dynamiques sans boucles

TOP liste

chaudétiquette

Archive