web-dev-qa-db-ja.com

状態配列にプッシュする正しい方法

データを状態配列にプッシュする問題があるようです。私はこのようにしてそれを達成しようとしています:

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

しかし、これは間違った方法であり、可変性の問題を引き起こすと思いますか?

71
Ilja

配列プッシュは長さを返す

this.state.myArray.Push('new value')は、配列そのものではなく、拡張配列の長さを返します。

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

戻り値が配列であることを期待していると思います。

不変性

それはむしろReactの振る舞いだと思われます。

後でsetState()を呼び出すと、行った変更が置き換えられる可能性があるため、this.stateを直接変更しないでください。これが不変であるかのようにthis.stateを扱います。

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

私は思います、あなたはこのようにするでしょう(Reactに慣れていない):

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

Es6を使うと、これは次のようになります。

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

スプレッド構文

94

状態を直接変更することは絶対にお勧めしません。

最近のReactバージョンで推奨されるアプローチは、競合状態を防ぐために状態を変更するときにアップデータ関数を使うことです。

文字列を配列の末尾にプッシュする

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

文字列を配列の先頭にプッシュする

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

オブジェクトを配列の末尾にプッシュする

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

オブジェクトを配列の先頭にプッシュする

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

.concat メソッドを使用して、新しいデータで配列のコピーを作成できます。

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

しかし、配列を渡すときの.concatメソッドの特別な振る舞いに注意してください - [1, 2].concat(['foo', 3], 'bar')[1, 2, 'foo', 3, 'bar']になるでしょう。

11
Ginden

あなたはその状態をまったく操作してはいけません。少なくとも直接ではありません。もしあなたがあなたの配列を更新したいのなら、あなたはこのようなことをしたいでしょう。

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

状態オブジェクトを直接操作することは望ましくありません。 Reactの不変性ヘルパーも見てください。

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

10
Christoph

このコードは私のために働きます:

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

反応ネイティブ

また、u UI(つまりur flatList)を最新の状態にしたい場合は、PrevStateを使用します。以下の例では、ユーザーがボタンをクリックすると、新しいオブジェクトがリストに追加されます(モデルとUIの両方)。 )

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