Maison  >  Questions et réponses  >  le corps du texte

Comment utiliser setState pour mettre à jour state.item dans l'état ?

<p>Je crée une application dans laquelle les utilisateurs peuvent concevoir leurs propres formulaires. Par exemple. Spécifiez le nom du champ et les détails des autres colonnes qui doivent être incluses. </p> <p>Ce composant est disponible en tant que JSFiddle. </p> <p>Mon état initial ressemble à ceci : </p> <pre class="brush:php;toolbar:false;">var DynamicForm = React.createClass({ getInitialState : fonction() { var éléments = {} ; items[1] = { nom : 'champ 1', populate_at : 'web_start', identique_à : 'nom_client', autocomplete_from : 'nom_client', titre : '' } ; items[2] = { nom : 'champ 2', populate_at : 'web_end', identique_à : 'nom_utilisateur', autocomplete_from : 'nom_utilisateur', titre : '' } ; retourner les articles }; }, rendu : fonction() { var _this = ceci ; retour ( <div> { Object.keys(this.state.items).map(function (clé) { var item = _this.state.items[clé]; retour ( <div> <PopulateAtCheckboxes this={this} vérifié={item.populate_at} id={clé} populate_at={data.populate_at} /> </div> ); }, ce)} <button onClick={this.newFieldEntry}>Créer un nouveau champ</button> <button onClick={this.saveAndContinue}>Enregistrer et continuer</button> </div> ); }</pré> <p>Je souhaite mettre à jour l'état lorsque l'utilisateur modifie une valeur, mais j'ai du mal à localiser l'objet correct : </p> <pre class="brush:php;toolbar:false;">var PopulateAtCheckboxes = React.createClass({ handleChange : fonction (e) { item = this.state.items[1]; item.name = 'nouveauNom'; articles[1] = article ; this.setState({éléments : éléments}); }, rendu : fonction() { var populateAtCheckbox = this.props.populate_at.map(function(value) { retour ( <étiquette pour={valeur}> <input type="radio" name={'populate_at'+this.props.id} value={value} onChange={this.handleChange} vérifié={this.props.checked == valeur} ref="populate-at"/> {valeur} </étiquette> ); }, ce); retour ( <div className="populate-at-checkboxes"> {populateAtCheckbox} </div> ); } });</pré> <p>Comment dois-je créer <code>this.setState</code> pour qu'il mette à jour <code>items[1].name</code> ? </p>
P粉464208937P粉464208937394 Il y a quelques jours363

répondre à tous(2)je répondrai

  • P粉798343415

    P粉7983434152023-08-24 12:39:53

    Vous pouvez utiliser l'assistant d'immuabilité 更新 pour y parvenir  :

    this.setState({
      items: update(this.state.items, {1: {name: {$set: 'updated field name'}}})
    })

    Alternativement, si vous ne vous souciez pas de pouvoir détecter les modifications apportées à cela à l'aide des méthodes de cycle de vie ===shouldComponentUpdate(), vous pouvez modifier l'état directement et forcer le rendu du composant - c'est en fait la même chose que la réponse de @limelights, car elle sort l'objet de l'état et le modifie.

    this.state.items[1].name = 'updated field name'
    this.forceUpdate()

    Modification ultérieure ajoutée :

    Consultez les leçons de Simple Component Communication react-training pour un exemple de la façon de transmettre une fonction de rappel d'un composant parent en état de maintien à un composant enfant qui doit déclencher un changement d'état.

    répondre
    0
  • P粉709307865

    P粉7093078652023-08-24 12:38:33

    Voici comment procéder sans bibliothèques d'assistance :

    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 intested 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});
    },

    Vous pouvez combiner les étapes 2 et 3 si besoin :

    let item = {
        ...items[1],
        name: 'newName'
    }

    Ou vous pouvez tout faire en une seule ligne :

    this.setState(({items}) => ({
        items: [
            ...items.slice(0,1),
            {
                ...items[1],
                name: 'newName',
            },
            ...items.slice(2)
        ]
    }));

    Remarque : j'ai créé items sous forme de tableau. OP a utilisé un objet. Cependant, le concept est le même.


    Vous pouvez voir ce qui se passe dans le terminal/console :

    ❯ node
    > items = [{name:'foo'},{name:'bar'},{name:'baz'}]
    [ { name: 'foo' }, { name: 'bar' }, { name: 'baz' } ]
    > clone = [...items]
    [ { name: 'foo' }, { name: 'bar' }, { name: 'baz' } ]
    > item1 = {...clone[1]}
    { name: 'bar' }
    > item1.name = 'bacon'
    'bacon'
    > clone[1] = item1
    { name: 'bacon' }
    > clone
    [ { name: 'foo' }, { name: 'bacon' }, { name: 'baz' } ]
    > items
    [ { name: 'foo' }, { name: 'bar' }, { name: 'baz' } ] // good! we didn't mutate `items`
    > items === clone
    false // these are different objects
    > items[0] === clone[0]
    true // we don't need to clone items 0 and 2 because we're not mutating them (efficiency gains!)
    > items[1] === clone[1]
    false // this guy we copied

    répondre
    0
  • Annulerrépondre