2017-09-30 2 views
0

Dans le gestionnaire d'événement onChange, je ne fais qu'un appel à setState() sur le userTxt mais il semble qu'il définit également l'état de l'objet de couleur. Ce qui est étrange pour moi, c'est que cela n'arrive qu'à l'objet couleur mais pas à la variable d'âge.Pourquoi SetState dans React met-il à jour d'autres objets dans le gestionnaire?

Je me demandais si quelqu'un pouvait expliquer pourquoi cela se produit? Here is a link to my webpackbin example. As you write in the input, the state is changed on the color object..

J'espérais que quelqu'un pourrait m'expliquer les mécanismes expliquant pourquoi cela se passe. Merci beaucoup d'avance.

import React, { Component } from 'react'; 

export default class Hello extends Component { 

    constructor() { 
    super(); 
    this.handleMe = this.handleMe.bind(this); 
    this.state = { 
     age: 21, 
     colors: { 
      best: 'blue', 
      second: 'green' 
     }, 
     userTxt: "" 
    } 
    } 
    handleMe(e) { 
     let myAge = this.state.age; 
     let myColors = this.state.colors; 

     myAge = myAge + 1; 
     myColors['best'] = 'mistyrose'; 
     myColors['second'] = 'red'; 

     this.setState({ userTxt: e.target.value }); 
    } 

    render() { 
    const { age, colors, userTxt} = this.state; 
    return (
     <div> 
     <form action=""> 
      <input type="text"onChange={this.handleMe}/> 
      <div>Age: {age}</div> 
      <div>Colors - best: {colors.best}</div> 
      <div>Colors - second: {colors.second}</div> 
      <div>UserTxt: {userTxt}</div> 
     </form> 
     </div> 
    ) 
    } 
}[enter link description here][1] 


    [1]: https://www.webpackbin.com/bins/-KvFx-s7PpQMxLH0kg7m 

Répondre

1

Le champ des couleurs dans l'état est un objet est stocké comme référence. Le champ d'âge est un nombre entier et est stocké en tant que valeur primitive.

Lorsque vous affectez le champ de couleur à myColors, les deux variables référencent le même objet. Ainsi, lorsque vous mettez à jour myColors, le champ de couleurs de l'état est mis à jour.

Lorsque vous affectez le champ d'âge à myAge, il copie la valeur du champ d'âge dans l'état dans le champ myAge. Ainsi, lorsque vous mettez à jour myAge, il ne met pas à jour l'état.

Plus sur ce sujet à Primitive value vs Reference value

Pour éviter cet effet secondaire involontaire, vous devez créer un nouvel objet et copier les valeurs des couleurs de l'état à elle. Vous pouvez le faire en utilisant

let myColors = {...this.state.colors};

en déclarant la variable.

1

Cela se produit car vous manipulez directement l'état ici. myColors fait référence à l'objet de couleurs de l'état.

handleMe(e) { 
     let myAge = this.state.age; 
     let myColors = this.state.colors; 

     myAge = myAge + 1; 
     //directly mutating the state with these 2 lines. 
     myColors['best'] = 'mistyrose'; 
     myColors['second'] = 'red'; 

     this.setState({ userTxt: e.target.value }); 
    } 

Vous devez faire une copie de this.state.colors comme laisser mycolors = Object.assign ({}, this.state.colors)