Props — コンポーネントにデータを渡す
このトピックを終えると
propsの動作原理、childrenの役割、そしてprop drillingとは何かを理解できます。
Propsとは
HTMLタグに属性を入れるように、Reactコンポーネントにもデータを入れられます。
<UserCard name="Alice" age={25} />この name と age が props(プロパティ) です。親コンポーネントが子コンポーネントにデータを渡す方法です。
受け取る側
function UserCard({ name, age }) {
return (
<div>
<h2>{name}</h2>
<p>{age}years old</p>
</div>
);
}構造分解を使って、必要なpropsだけを取り出して使います。propsオブジェクトをまとめて受け取ることもできます。
function UserCard(props) {
return <h2>{props.name}</h2>;
}Propsは読み取り専用
function UserCard({ name }) {
name = "Bob"; // 動作するが、すべきではない
return <h2>{name}</h2>;
}Reactでは、propsは読み取り専用として扱うべきです。親から渡されたデータを子が自由に書き換えると、データフローが混乱します。
値を変更したい場合は、親で状態を管理し、変更関数をpropsとして渡します。
function Parent() {
const [name, setName] = useState("Alice");
return <Child name={name} onNameChange={setName} />;
}
function Child({ name, onNameChange }) {
return <input value={name} onChange={e => onNameChange(e.target.value)} />;
}デフォルト値
propsが渡されなかったときのデフォルト値を設定できます。
function Button({ label = "Click", size = "medium" }) {
return <button className={size}>{label}</button>;
}
<Button /> // label="Click", size="medium"
<Button label="Save" /> // label="Save", size="medium"children — 特別なprop
タグの間に配置した内容は、children propとして渡されます。
function Card({ children }) {
return <div className="card">{children}</div>;
}
<Card>
<h2>Title</h2>
<p>Content</p>
</Card>レイアウトコンポーネントを作成する際に便利です。ラップする構造を再利用しながら、内部の内容だけを変更できます。
Prop Drilling
<App> → user
<Layout> → user
<Sidebar> → user
<Avatar> → user.name ここでのみ使用データが中間コンポーネントを介して渡されることを prop drilling と言います。中間コンポーネント(Layout、Sidebar)は user を使用しませんが、それでも渡す必要があります。
2〜3段階までは問題ありませんが、それ以上に深くなると、Contextや状態管理ライブラリを検討します。
重要なポイント
Propsは、親が子にデータを渡す方法であり、読み取り専用です。
childrenは、タグ間の内容を渡す特別なpropです。 データ伝達が深くなると、prop drilling の問題が発生します。