最近React製の静的サイトジェネレーター「Gatsby」でブログを作っていたら、Reactの関数コンポーネントにオブジェクトで引数(props)が渡されていて「なんだこれ?」ってなりました。
こんな感じ。
import React from "react"
// ↓関数コンポーネントのpropsがオブジェクトで指定されてる。何これ?
const Layout = ({ title, children }) => {
return (
<div>
<header className="global-header">
<h1>{title}</h1>
</header>
<main>{children}</main>
<footer>
...
</footer>
</div>
)
}
export default Layout
「propsがオブジェクトの形で書かれてるってどういうこと?」
「どういう挙動になるの?」
「ってかそんなことできるのか」
という感じで困惑していましたが、わかってしまえばどうってことないです。
というわけで今回はこれの解説をします。
その1.Reactでよくあるのpropsの書き方
オブジェクトの形をした引数を理解するために、まずは多くの人が最初にやるであろう書き方を見てみます。
自己紹介文を表示する簡単なコンポーネントを例に考えてみます。Profile.jsが子コンポーネントです。
// Profile.js
import React from 'react'
const Profile = props => {
console.log(props)
return (
<p>私は{props.name}です。{props.age}歳です</p>
)
}
export default Profile
index.jsで<Profile />
コンポーネントをインポートします。propsに値を入れるときは変数に入れるかベタ書きすると思います。
import React from 'react'
import Profile from './Profile.js'
const App = () => {
return (
<Profile name={`田中`} age={29} />
)
}
export default App
// 結果
// 私は田中です。29歳です
関数コンポーネントの引数にpropsと書き、プロパティの部分をprops.****
って書くのがよくある書き方ですよね。
<Profile />
コンポーネントでconsole.log(props)
しているので、propsの中身を確認するとこんな感じになっています。
// console.log(props)
Object {name: "田中", age: 29}
propsがオブジェクトになっています。
知らなかった人は知っておいて欲しいのですが、Reactのpropsってオブジェクトになっているんですよね。
props: {
name: "田中",
age: 29,
}
という形で入っています。プロパティが1つでもオブジェクトの形をしています。
ということはですよ?
オブジェクトになっているということは、「ES6の分割代入が使える」ということです。
その2.propsを分割代入する
propsを分割代入してみます。
import React from 'react'
const Profile = props => {
// propsを分割代入
const { name, age } = props
return (
<p>私は{name}です。{age}歳です</p>
)
}
export default Profile
この様に書くとプロパティを指定したい箇所で毎回props.
と書く必要がなくなり、少しですがコードの見通しが良くなりました。
また、分割代入をするとプロパティを1箇所でまとめて宣言できるので、コード量が増えた場合にどこにどんなプロパティがあるのか探す必要がなくなります。
ちなみに分割代入せずに普通に書くとこんな感じになります。
// 分割代入
const { name, age } = props
// 通常
const name = props.name
const age = props.age
分割代入は配列やオブジェクトの中の要素をそのまま取得できる仕組みです。
そしてpropsはオブジェクトです。
ということはですよ?
関数コンポーネントの引数で渡すpropsの部分を分割代入で指定しちゃえば、プロパティをそのまま直接書けるってことです。
その3.関数コンポーネントのpropsを分割代入で指定
引数を分割代入で指定します。
import React from 'react'
// 関数コンポーネントのpropsを分割代入で指定(最初にみたやつ!)
const Profile = ({ name, age }) => {
return (
<div>私は{name}です。{age}歳です</div>
)
}
export default Profile
({ name, age })
の部分はprops.name
、props.age
と同じ意味です。
今までの書き方は引数の部分がpropsとなっていましたが、分割代入を使えば毎回props.
と書かなくていい上、どんな名前のプロパティが何個あるのかを全ファイル同じ場所で確認できるというわけです!これはすごい便利ですね…。
つまりこれが最初に言ってた、引数がオブジェクトで指定されている書き方の正体です。
props.****
の部分を分割代入でそのまま宣言していたということですね。
あと分割代入するなら引数は({ })
と書くことに注意しておきましょう。
ちなみにプロパティが1つでも分割代入で指定できます。
import React from 'react'
const Profile = ({ name }) => {
return (
<p>私は{name}です</p>
)
}
export default Profile
純粋にprops.
って書く手間が省けるっていうのと、プロパティ名がそのままわかるのでこれだけでもメリットがありますね。
まとめ
Reactで関数コンポーネントの引数がオブジェクトの形で指定されているのは、props.****
の部分を分割代入で宣言しているからでした。言われてみればなるほどって感じ。
普通に便利な書き方なのでpropsの指定は全部これでいいんじゃないかなって気がしますね。どうなんでしょうか。