React の props と state - 違いとデザインパターン
React は、学ぶのが最も簡単な JavaScript フレームワークの 1つです。ただし、このライブラリには、最初は混乱しているように思われるいくつかの概念が導入されています。たとえば、多くの初心者は、props と state の違いを理解するのが困難です。この記事では、これらのオブジェクトの両方が必要な理由と、それらの最適な使用法を見つける方法を学習します。
React の state について
state の概念は、React またはそれを利用する他の JavaScript フレームワークに固有のものではありません。バニラ JavaScript で構築された一部のアプリケーションでさえ、state を持つことができます。React では、概念は少し異なりますが、同じ原則に基づいています。
すべての React コンポーネントは、そのローカル state オブジェクトを維持します。状態管理は内部で行われます。state オブジェクトは変更可能です。それを変更することは、ユーザーのアクションに応じて変化する動的な React コンポーネントを開発するための鍵です。
親コンポーネントは、その子の状態を変更できません。state の値は、プレーンな JavaScript 関数のローカル変数と考えることができます。これらの変数は関数スコープに制限されています。
React では、state オブジェクトの主な目的は、動的アプリケーションを強化するすべてのデータの保守を簡素化することです。state オブジェクトの値を変更すると、コンポーネントの再レンダリングがトリガーされます。このように、ユーザー入力が変更されると、ユーザーのビューは常に即座に更新されます。
React の props について
props(properties の略)オブジェクトは、親コンポーネントのデータを子と共有するために使用されます。props は、コンポーネントの動作をカスタマイズするためにコンポーネントに渡される設定と考えることができます。ビジュアルをレンダリングする <Bargraph/> コンポーネントがあるとします。このようなコンポーネントでは、グラフをレンダリングするために数値が必要です。すべてのグラフは異なるデータをレンダリングし、それらは props を介してそれらに供給することができます。これは、props がコンポーネントの再利用性を促進する方法の一例にすぎません。
すべてのコンポーネントは、コンポーネント内で不変の props オブジェクトを受け取ります。ただし、関数に異なる引数を渡すことができるのと同じように、同じコンポーネントの多くのインスタンスは、props を介して異なる値を受け取ることができます。
内部的には、React は React.createElement() メソッドを使用して React コンポーネントを作成し、props を渡します。ただし、React 開発者は、より使い慣れた JSX 構文を使用して React アプリケーションを構築する傾向があります。この HTML に似た構文は、props を渡すためのより読みやすい方法を提供します。
const Graph=(props)=>
{
return <div>
<h1>{props.data.percentage}%</h1>
</div>;
}
class App extends Component {
constructor(props){
super(props)
this.state = {
data: {percentage: "70"}
}
}
render() {
return <Graph data={this.state.data}>Hi! Try edit me</Graph>;
}
}
これは、props がどのように機能するかを示す非常に簡単なデモンストレーションです。まず、子コンポーネントを定義します。ご覧のとおり、子コンポーネントはその状態を維持していません。props を介して渡されたデータのみを読み取ります。
次に、親コンポーネントがあります。子コンポーネントとは異なり、state オブジェクトからのデータを使用して、props として渡します。ご覧のとおり、JSX 構文は通常の HTML と同じではありません。
React の props の構造改革
上記の例でわかるように、すべての機能コンポーネントは props 引数を受け入れます。props オブジェクトに格納されているデータには、JSX の属性と同じ名前のプロパティを読み取ることでアクセスできます。
より簡単な方法は、関数定義内の props を分解することです。構造化されていない props を備えた Graph 機能コンポーネントの例を次に示します。
const Graph=({data = { percentage: 50 } })=>
{
return <div>
<h1>{{data.percentage}}%</h1>
</div>;
}
これにより、より単純な構文を使用したり、デフォルトの prop 値を設定したりすることができます。子コンポーネントが props を受け取らない場合、コンポーネントは代わりにデフォルト値を読み取ることができます。
React における state と props のつながり
前に述べたように、React コンポーネント内では、props オブジェクトは厳密に不変です。ただし、注意点が 1つあります。子コンポーネントは、親コンポーネントの状態を変更できます。親コンポーネントは、props を介して子に返されるデータのソースとして使用されます。これを理解するのが難しい場合は、次のコードサンプルを調べてみましょう。
const Graph=(props)=>
{
const {handler, color} = props
return <div
style={{width: "400px", height: "400px", border: "2px solid black", backgroundColor: `${color}`}}>
<h1>{props.data.percentage}%</h1>
<input type="text" onChange={(e) => handler(e)}/>
</div>;
}
class App extends Component {
constructor(props){
super(props)
this.state = {
data: {percentage: "70"},
bgColor: "black"
}
}
render() {
const backgroundHandler = (e) => this.setState({color: e.target.value})
return <Graph data={this.state.data} color={this.state.bgColor} handler={backgroundHandler}>
Hi! Try edit me</Graph>;
}
}
この例では、以前に使用したものと同じ 2つのコンポーネントがまだあります。props を介してイベントハンドラーを渡します。次に、同じハンドラーを使用して、親コンポーネントの状態の color プロパティを更新します。親コンポーネントの状態の値が変更されると、再レンダリングされ、更新された color 値が子コンポーネントに渡されます。
これは、子コンポーネントが独自の props を更新するように見えるかもしれませんが、この例では、実際には、props を介して渡されたイベントハンドラーを使用して、独自の props のソース(親コンポーネントの状態の color プロパティの値)を更新します。
playcode へのリンクは次のとおりです。自分で試してみてください。テキストフィールドに色を入力して、何が起こるかを確認してください。
これは、プロパティと state がどのように相互接続されているかを示す代表的な例です。親コンポーネントの状態は通常、props を介してすべての子に渡されるデータのソースです。
この例では、bgColor 状態プロパティに格納されている状態値は color プロップになります。
この例は、state と props がデータを保存してそのフローを管理するための 2つの方法にすぎないことを示しています。
React で state と props を使用する場合
どちらかを選択するのではなく、コンポーネントが state を維持し、props も受け取るのが一般的です。州に保存されているデータの断片は、多くの場合、子供のコンポーネントの props になります。props はデータに限定されず、コールバック関数を含めることもできます。
管理しやすい React アプリを構築するには、コンポーネントツリーの上位にあるコンポーネントの状態を使用します。他のすべてのコンポーネントはステートレスであり、props を介して必要なデータを受け取る必要があります。ステートレスコンポーネントは、読みやすく、テストしやすいため、推奨されます。
要約すると、state と props の両方が必要であり、props は state なしでは効果的ではありません。一般に、イベント処理とデータ処理にはステートフルコンポーネントを使用する方が適切ですが、視覚化とフォーマットにはステートレスコンポーネントを使用する方が適切です。
Irakli is a writer who loves computers and helping people solve their technical problems. He lives in Georgia and enjoys spending time with animals.
LinkedIn