【React】はじめてのProps
一冊目に買ったReactの本が私には少し難しすぎて挫折気味でしたが、「モダンJavaScriptの基本から始める React実践の教科書」という本が読みやすく、なんとかほぼ全て読み終えることができました。整理と備忘録として、Reactの重要な機能の一つであるPropsについて、本を参考にまとめたいと思います。なお、同じく本で紹介されていたcodesandboxというサイトで手軽にオンラインでReactを試せるので、そちらを使いながら進めます。
Props
概要
Propsは「コンポーネントに渡す引数のようなもの」です。親コンポーネントから子コンポーネントにPropsとしてデータを渡してあげるだけで、表示内容やデザインなどを指定することができるようになります。
Propsを使わないと困る場面
今回は”カレー”と”ラーメン”という2つの文字をpタグを使って縦に並べています。文字の色とフォントサイズをしているcontentBlue
、contentRed
というオブジェクトをそれぞれに指定することでスタイルを指定しています。
表示:
import "./styles.css";
contentBlue = {
color: "blue",
fontSize: "18px",
};
contentRed = {
color: "red",
fontSize: "18px",
};
export default function App() {
return (
<div className="App">
<p style={contentBlue}>カレー</p>
<p style={contentRed}>ラーメン</p>
</div>
);
}
まだ要素が2つなのでいいですが、これがもっと増えた場合、スタイルの定義部がどんどん膨大になってしまいます。そもそも色以外のスタイルの指定は共通しているので冗長です。そこで、Propsを使うことでこの問題を解消します。
Propsを使った解決
今回は参考書に倣い、componentsディレクトリをsrcディレクトリ直下に作成し、その中にColoredMessage.jsx
を作成しました。
export const ColoredMessage = (props) => {
const contentStyle = {
color: props.color,
fontSize: "18px",
};
return <p style={contentStyle}>{props.message}</p>;
};
ポイントは親コンポーネントであるApp.jsxから渡されてくるデータ(Props)をprops
という仮引数を使って受け取ってあげる点です。今回は色と表示内容をそれぞれcolor
とmessage
として親コンポーネントが渡してくることを想定しています。
App.jsxもPropsを渡すよう一部修正します。
import "./styles.css";
import { ColoredMessage } from "./components/ColoredMessage";
// contentBlue = {
// color: "blue",
// fontSize: "18px",
// };
// contentRed = {
// color: "red",
// fontSize: "18px",
// };
export default function App() {
return (
<div className="App">
{/* <p style={contentBlue}>カレー</p> */}
{/* <p style={contentRed}>ラーメン</p> */}
<ColoredMessage color="blue" message="カレー" />
<ColoredMessage color="red" message="ラーメン" />
</div>
);
}
変更箇所はコメントアウトしてあります。スタイルの指定はColoredMessage.jsxが担当するようになったのでcontentBlue
とcontentRed
の定義は不要になり、かつreturn
部でcolorとmessageをPropsとして渡すためにタグ内で指定してあげています。これで、表示は変わりませんがPropsを使ってより簡潔にスタイルの指定ができるようになりました。
childrenの利用
先ほどの例のようにPropsとして渡すデータをタグ内に指定する以外に、タグで囲った部分をPropsとして渡すこともできます。そのようにして渡すPropsをchildren
と呼ぶようです。
試しにmessage
の部分をchildrenとして渡すように変更してみます。
export const ColoredMessage = (props) => {
const contentStyle = {
color: props.color,
fontSize: "18px",
};
return <p style={contentStyle}>{props.children}</p>;
};
ColoredMessage.jsxでの変更点は{props.message}
を{props.children}
にしただけです。そして、以下のようにchildrenとして渡すデータである表示内容の言葉をタグで囲ってあげます。
import "./styles.css";
import { ColoredMessage } from "./components/ColoredMessage";
export default function App() {
return (
<div className="App">
<ColoredMessage color="blue">カレー</ColoredMessage>
<ColoredMessage color="red">ラーメン</ColoredMessage>
</div>
);
}
こちらの方が普通のHTMLタグと同じように使えるので、直感的です。ちなみに一つのタグで囲ってあげれば複数の要素をchildrenとして渡すことも可能です。
import "./styles.css";
import { ColoredMessage } from "./components/ColoredMessage";
export default function App() {
return (
<div className="App">
<ColoredMessage color="blue">
<div>
<p>カレー</p>
<p>サラダ</p>
</div>
</ColoredMessage>
<ColoredMessage color="red">ラーメン</ColoredMessage>
</div>
);
}
表示:
上の例では
<div>
<p>カレー</p>
<p>サラダ</p>
</div>
という部分が丸ごとchildrenとして子コンポーネントに渡されています。カレー、サラダどちらにも青色のスタイルが適用されていることからもそれがわかります。
分割代入と省略記法でより効率よく
分割代入を用いることでprops.~
という部分をいちいち書かなくてよくなります。
export const ColoredMessage = (props) => {
{ color, children } = props;
const contentStyle = {
color: color,
fontSize: "20px",
};
return <p style={contentStyle}>{children}</p>;
};
さらにcolorというプロパティ名とpropsとして渡される変数名は全く同じなので省略することができます。
export const ColoredMessage = (props) => {
{ color, children } = props;
const contentStyle = {
color, // 省略記法
fontSize: "20px",
};
return <p style={contentStyle}>{children}</p>;
};
このあたりの話は、同じく本を参考にした以下の記事でまとめたため、不安な方はそこも含めて勉強すると今後ためになると思います。
まとめ
Propsはかなり利用頻度が高そうなので、最初の方で基礎をしっかり理解していきたいですね。参考にさせていただいた本はより詳しくこの話が紹介されていて、とてもわかりやすかったので、著者の方には感謝しかないです。
参考文献
「モダンJavaScriptの基本から始める React実践の教科書」
Discussion