Comment mettre à jour un objet dans un état imbriqué à l'aide de setState dans React
Dans React, il est courant de rencontrer des objets d'état imbriqués qui nécessitent un ciblage mises à jour basées sur les entrées de l'utilisateur. Considérez l'extrait de code suivant :
var DynamicForm = React.createClass({ getInitialState: function() { var items = {}; items[1] = { name: 'field 1', populate_at: 'web_start', same_as: 'customer_name', autocomplete_from: 'customer_name', title: '' }; items[2] = { name: 'field 2', populate_at: 'web_end', same_as: 'user_name', autocomplete_from: 'user_name', title: '' }; return { items }; }, render: function() { var _this = this; return ( <div> { Object.keys(this.state.items).map(function (key) { var item = _this.state.items[key]; return ( <div> <PopulateAtCheckboxes this={this} checked={item.populate_at} id={key} populate_at={data.populate_at} /> </div> ); }, this)} <button onClick={this.newFieldEntry}>Create a new field</button> <button onClick={this.saveAndContinue}>Save and Continue</button> </div> ); } });
Dans ce composant, l'état est constitué d'un objet imbriqué, items, qui contient des éléments indexés par leur position. Cependant, l'objectif est de mettre à jour un élément spécifique dans l'objet items lors de l'interaction de l'utilisateur.
var PopulateAtCheckboxes = React.createClass({ handleChange: function (e) { item = this.state.items[1]; item.name = 'newName'; items[1] = item; this.setState({items: items}); }, render: function() { var populateAtCheckbox = this.props.populate_at.map(function(value) { return ( <label for={value}> <input type="radio" name={'populate_at'+this.props.id} value={value} onChange={this.handleChange} checked={this.props.checked == value} ref="populate-at"/> {value} </label> ); }, this); return ( <div className="populate-at-checkboxes"> {populateAtCheckbox} </div> ); } });
Bien que l'approche ci-dessus tente de mettre à jour l'état, ce n'est pas la méthode recommandée pour muter les objets d'état imbriqués dans React. Pour garantir l'immuabilité et éviter les effets secondaires indésirables, l'approche correcte consiste à créer une copie superficielle de l'objet d'état, puis à modifier la copie et enfin à définir l'état sur la copie modifiée.
handleChange: function (e) { // 1. Make a shallow copy of the items let items = [...this.state.items]; // 2. Make a shallow copy of the item you want to mutate let item = {...items[1]}; // 3. Replace the property you're interested in item.name = 'newName'; // 4. Put it back into our array. N.B. we *are* mutating the array here, // but that's why we made a copy first items[1] = item; // 5. Set the state to our new copy this.setState({items}); },
Alternativement, si vous préférez une approche plus concise, vous pouvez utiliser la syntaxe spread pour obtenir le même résultat sur une seule ligne :
this.setState(({items}) => ({ items: [ ...items.slice(0,1), { ...items[1], name: 'newName', }, ...items.slice(2) ] }));
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!