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