web-dev-qa-db-fra.com

Manière correcte de pousser dans le tableau d'état

Je semble avoir des problèmes pour insérer des données dans un tableau d'état ... Je tente d'y parvenir de cette façon:

this.setState({ myArray: this.state.myArray.Push('new value') })

Mais je crois que ceci est incorrect et cause des problèmes de mutabilité?

47
Ilja

Longueur du retour de Push Array

this.state.myArray.Push('new value') renvoie la longueur du tableau étendu, au lieu du tableau lui-même.

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/Push

Je suppose que vous vous attendez à ce que la valeur renvoyée soit le tableau.

Immutabilité

Il semble que ce soit plutôt le comportement de React:

NE JAMAIS muter this.state directement, car appeler ensuite setState () peut remplace la mutation que tu as faite. Traitez cet Etat comme si c’était immuable.

https://facebook.github.io/react/docs/component-api.html

J'imagine que vous le feriez comme ceci (non familier avec React):

var joined = this.state.myArray.concat('new value');
this.setState({ myArray: joined })
61
Tamás Márton

En utilisant es6, cela peut être fait comme ceci:

this.setState({ myArray: [...this.state.myArray, 'new value'] }) //simple value
this.setState({ myArray: [...this.state.myArray, ...[1,2,3] ] }) //another array

Syntaxe Spread

72

Jamais recommandé de muter l'état directement.

L'approche recommandée dans les versions ultérieures de React consiste à utiliser une fonction de mise à jour lors de la modification d'états pour éviter les conditions de concurrence:

Pousser la chaîne à la fin du tableau

this.setState(prevState => ({
  myArray: [...prevState.myArray, "new value"]
}))

Pousse la chaîne au début du tableau

this.setState(prevState => ({
  myArray: ["new value", ...prevState.myArray]
}))

Poussez l'objet à la fin du tableau

this.setState(prevState => ({
  myArray: [...prevState.myArray, {"name": "object"}]
}))

Pousser l'objet au début du tableau

this.setState(prevState => ({
  myArray: [ {"name": "object"}, ...prevState.myArray]
}))
25
Hemadri Dasari

Vous pouvez utiliser .concat pour créer une copie de votre tableau avec de nouvelles données:

this.setState({ myArray: this.state.myArray.concat('new value') })

Attention toutefois au comportement spécial de la méthode .concat lors du passage de tableaux - [1, 2].concat(['foo', 3], 'bar') donnera [1, 2, 'foo', 3, 'bar'].

10
Ginden

Vous ne devriez pas faire fonctionner l'état du tout. Du moins pas directement. Si vous souhaitez mettre à jour votre tableau, vous voudrez faire quelque chose comme ceci.

var newStateArray = this.state.myArray.slice();
newStateArray.Push('new value');
this.setState(myArray: newStateArray);

Travailler directement sur l'objet d'état n'est pas souhaitable. Vous pouvez également consulter les aides à l'immutabilité de React.

https://facebook.github.io/react/docs/update.html

8
Christoph

Ce code fonctionne pour moi:

fetch('http://localhost:8080')
  .then(response => response.json())
  .then(json => {
  this.setState({mystate: this.state.mystate.Push.apply(this.state.mystate, json)})
})
0
Hamid Hosseinpour

React-Native

si vous voulez également que votre interface utilisateur (c'est-à-dire votre liste à plat) soit à jour, utilisez PrevState: dans l'examen ci-dessous. Si l'utilisateur clique sur le bouton, il va ajouter un nouvel objet à la liste (les deux modèle et l'interface utilisateur)

data: ['shopping','reading'] // declared in constructor
onPress={() => {this.setState((prevState, props) => {
return {data: [new obj].concat(prevState.data) };
})}}. 
0
Mahgol Fa