私のコードは動作しますが、私はベストプラクティスの質問があります。私は状態のオブジェクトの配列を持っており、ユーザーのやり取りは一度に1つのオブジェクトの値を変更します。限り、私は知っている限り、私は直接国を変更するはずはない、私は常にsetState
を使用する必要があります。もし私がそれを避けたいなら、私は反復によって配列を深くクローンし、クローンを変更します。次に、状態をクローンに設定します。私の意見では、後で変更する状態を変更することを避けることは、単にパフォーマンスを低下させることです。React - setStateを使用せずに状態を変更する:回避する必要がありますか?
詳細バージョン: this.state.dataはオブジェクトの配列です。それはフォーラム内のトピックのリストを表し、FavoriteボタンはclickCollect()
を呼び出してトグルします。 私は状態の配列を持っているので、1つのアイテムのis_collectedプロパティを変更するときは、作業する配列のコピーを作成し、新しい値に変更した後に状態に設定する必要があります。
var data = this.state.data.slice(0); data[index].is_collected = !data[index].is_collected; this.setState({data: data});
var data = this.state.data
:これはアレイ及びプッシュ(へのポインタをコピーする)、等シフト()は、直接、状態を変化させるであろう。 data
とthis.state.data
の両方が影響を受けます。
var data = this.state.data.slice(0)
:これは浅いクローンを作成しますが、pushとshiftは状態を変更しませんが、私のクローンではまだステートの配列の要素へのポインタを持っています。だから私がdata[0].is_collected
を変更した場合、this.state.data[0].is_collected
も同様に変更されます。これは私がsetState()
に電話する前に起こります。
その後var data = []; for (var i in this.state.data) { data.push(this.state.data[i]); }
それは本当だとき、それは虚偽または虚偽だとき、私はこれをtrueに設定し、インデックスの値を変更します。
data[index].is_collected = !data[index].is_collected;
状態を変更:
this.setState({data: data});
私の配列が比較的大きいか、非常に大きいです考えてみて、私はこの繰り返しが私のAPPのパフォーマンスが低下しますね。私はそれが何らかの理由で正しい方法であることが分かっていれば、私はその費用を支払うでしょう。ただし、この関数(clickCollect
)では、常に新しい値を状態に設定していますが、変更をやめるのを止める偽のAPI応答を待っているわけではありません。すべての場合、新しい値が状態に入ります。実際には、setState
は、UIを再レンダリングするためだけに呼び出します。したがって、質問は次のとおりです。
- この場合、ディープクローンを作成する必要がありますか? (
for var i in ...
) - 私の配列にオブジェクトが含まれている場合、浅いクローン(
.slice(0)
)を作成するのは意味がありますか?変更はアレイ内部のオブジェクト上で行われているので、コピー(data = this.state.data
)のように、浅いクローンは自分の状態を変更します。
私のコードは単純化されており、簡単にするためにAPI呼び出しが省略されています。
これは初心者の質問です。全く異なるアプローチも歓迎します。あなたのアプリは非常に壊れやすい作りと基本的に全体を無視して、状態が直接(単方向とされている)のリアクトデータ・フローの主な原則を破るミュートまたは他のQへのリンク& A.
import React from 'react'; var ForumList = React.createClass({ render: function() { return <div className="section-inner"> {this.state.data.map(this.eachBox)} </div> }, eachBox: function(box, i) { return <div key={i} className="box-door"> <div className={"favorite " + (box.is_collected ? "on" : "off")} onTouchStart={this.clickCollect.bind(null, i)}> {box.id} </div> </div> }, getInitialState: function() { return {data: [ { id: 47, is_collected: false }, { id: 23, is_collected: false }, { id: 5, is_collected: true } ]}; }, clickCollect: function(index) { var data = this.state.data.slice(0); data[index].is_collected = !data[index].is_collected; this.setState({data: data}); } }); module.exports = ForumList;
ありがとうございました。私は4人すべてが異なる視点から問題にいくつかの光を当てているので、実際にはそれらのうちの1つを「受け入れる」ことはできません。しかし、@CodinCatは彼の答えをそう明確に述べるために受け入れを受けます。VJAI、Kelvin De Moyaとdegrに特別なおかげです。 –