命令型プログラムの最も重要な機能は、状態とその変更です。
ReactJs は、プログラミングの関数型スタイル (例えば、純度、高階関数の使用など) を奨励しています。ReactJs で不変の状態を使用する場合、この特性は依然として必須の機能であるか、機能的な「状態のスタイル」と見なすことができるかどうかを知りたいですか?
理論的には、React 状態と純粋な命令型プログラムの状態の違いは何ですか?
命令型プログラムの最も重要な機能は、状態とその変更です。
ReactJs は、プログラミングの関数型スタイル (例えば、純度、高階関数の使用など) を奨励しています。ReactJs で不変の状態を使用する場合、この特性は依然として必須の機能であるか、機能的な「状態のスタイル」と見なすことができるかどうかを知りたいですか?
理論的には、React 状態と純粋な命令型プログラムの状態の違いは何ですか?
理論的には、React 状態と純粋な命令型プログラムの状態の違いは何ですか?
React で( を使用して) 状態を更新する全体的な目的はthis.setState
、状態が更新されたことをコンポーネントに通知することであり、再レンダリングが必要です。
しかし、最終的に、React で状態 A から状態 B に変更したい場合は、イベント ハンドラー内で行います。これは、必要に応じて命令的に行うことができますが、初期状態を実際に変更せずに行う必要があります。例えば
// OK
let foo = this.state.foo;
foo = deriveSomeValue(foo);
this.setState({ foo });
// BAD
this.state.foo = deriveSomeValue(foo);
this.setState(this.state);
最初の例 (OK) では、確かに、ある程度の不純物が見られます。foo
変更されていますが、少なくとも元の状態は変更されていません。
2 番目の例 (BAD) では、同じレベルの不純物がありますが、さらに悪化しています。現在の状態を直接変更しているため、予測できない結果が生じる可能性があります。this.state
「X を使用して???を実行すると、正しくレンダリングされないのはなぜですか?」言い換えれば、この不変性パラダイムは実用的な理由で強制されます。つまり、React が動作するように設計された方法であり、他の方法では未定義の動作が発生します (ケースバイケースで)。
予測できない結果をもたらす別の例:
const foo = this.state.foo;
foo.someProperty = getSomeValue();
this.setState({ foo });
この場合、状態は React に通知する前に更新されます。(これは、オブジェクトが暗黙的にコピーされるのではなく、明示的に参照されるという事実に関係しています。)
確かに、React ではイベント ハンドラー内の命令型スタイルで状態 A から状態 B に移行できますが、初期状態が直接変更されないようにする必要があります。複雑な変更が必要であることが確実にわかっている場合は、オブジェクトのディープ コピーを実行してから、その方法で必要な変更を行うことをお勧めします。以下はまったく問題ありません。
const foo = cloneObject(this.state.foo);
// `cloneObject` is an entirely contrived function. You'll have to pick a
// deep copying library. Google around for "JavaScript deep copying"
foo.someProperty = getSomeValue();
this.setState({ foo });
別の方法として、不変のデータ構造を使用することもできます。これにより、(意味的に参照できるもの) プロパティを直接変更すると、必ずしも元のオブジェクトを変更することなく、まったく新しいオブジェクトが生成されます。そのための適切なライブラリは、(あなたが述べたように) ImmutableJS です。
let foo = this.state.foo;
foo = foo.set('someProperty', getSomeValue());
this.setState({ foo });