Part 0 · React の前に
分割代入とスプレッド構文
props の正体を読み解くための前提知識
React のコードには、見慣れない記号が 2 つよく出てきます。
const { name } = props の波括弧と、{ ...user, age: 21 } の 3 つの点です。
どちらも JavaScript の書き方で、React の機能ではありません。ただ、この 2 つを知らないと props も state の更新も読めません。 先に片付けておきます。
分割代入 — 必要なものだけ取り出す
オブジェクトから値を取り出すとき、ふつうはこう書きます。
const name = user.name;
const age = user.age;これを 1 行で書けるようにしたのが分割代入です。
const { name, age } = user;波括弧の中に書いた名前と同じ項目を、オブジェクトから探して取り出します。 順番は関係ありません。名前で見ています。
オブジェクトは名前で、配列は順番で取り出す
- オブジェクトから
- name は "さとう"、age は 20
- 配列から
- 1 つめは "赤"、2 つめは "青"
配列の場合は角括弧を使い、書いた順番で取り出されます。 配列の要素には名前がないためです。
destructuring.ts
const user = { name: "さとう", age: 20, city: "東京" };
// 必要なものだけ、名前を指定して取り出す
const { name, age } = user;
export const picked = `name は "${name}"、age は ${age}`;
// 配列は名前ではなく「順番」で取り出す
const colors = ["赤", "青", "緑"];
const [first, second] = colors;
export const firstTwo = `1 つめは "${first}"、2 つめは "${second}"`;props でよく見る形
分割代入は、関数の引数のところにも書けます。 React のコンポーネントはこの形をしていることがほとんどです。
// 受け取ってから取り出す
function Hello(props) {
const { name } = props;
return <p>{name} さん</p>;
}
// 受け取るところで直接取り出す(こちらが主流)
function Hello({ name }) {
return <p>{name} さん</p>;
}下の { name } は、オブジェクトを受け取ってその場で中身を取り出しています。引数が 1 つのオブジェクトであるという点は変わりません。
destructuring.ts
const user = { name: "さとう", age: 20, city: "東京" };
// 必要なものだけ、名前を指定して取り出す
const { name, age } = user;
export const picked = `name は "${name}"、age は ${age}`;
// 配列は名前ではなく「順番」で取り出す
const colors = ["赤", "青", "緑"];
const [first, second] = colors;
export const firstTwo = `1 つめは "${first}"、2 つめは "${second}"`;スプレッド構文 — 中身を展開する
... は「中身をその場に展開する」記号です。 新しいオブジェクトを作るときに使います。
const original = { name: "さとう", age: 20 };
const copied = { ...original };
// { name: "さとう", age: 20 } と書いたのと同じ
const updated = { ...original, age: 21 };
// 展開したあとに書いたものが勝つ{ ...original, age: 21 } は 「original の中身を全部並べて、そのあと age だけ書き直す」という意味です。 あとに書いたほうが勝つので、age が上書きされます。
新しいほうだけが変わり、元は残っている
- updated(新しく作ったもの)
- { name: "さとう", age: 21 }
- original(元のまま)
- { name: "さとう", age: 20 }
大事なのは、元のオブジェクトが変わっていないことです。 スプレッド構文は書き換えではなく、新しいものを作るための道具です。
spread.ts
const original = { name: "さとう", age: 20 };
// ... で中身を展開して、新しいオブジェクトを作る
export const copied = { ...original };
// 展開したあとに書けば、その項目だけ上書きできる
export const updated = { ...original, age: 21 };
// original はいっさい変わっていない
export const stillOriginal = original;配列でも同じことができる
const members = ["さとう", "すずき"];
// 末尾に足した新しい配列
const added = [...members, "たかはし"];
// 先頭に足した新しい配列
const addedToTop = ["やまだ", ...members];push は元の配列を書き換えてしまいますが、 この書き方なら元は残ったまま、新しい配列ができます。 React で配列の state を更新するときは、いつもこちらを使います。
spread.ts
const original = { name: "さとう", age: 20 };
// ... で中身を展開して、新しいオブジェクトを作る
export const copied = { ...original };
// 展開したあとに書けば、その項目だけ上書きできる
export const updated = { ...original, age: 21 };
// original はいっさい変わっていない
export const stillOriginal = original;理解できたか確かめる
確認クイズ
const [count, setCount] = useState(0) の角括弧は何をしている?
確認クイズ
const updated = { ...user, age: 21 } を実行したあと、user はどうなっている?
spread.ts
const original = { name: "さとう", age: 20 };
// ... で中身を展開して、新しいオブジェクトを作る
export const copied = { ...original };
// 展開したあとに書けば、その項目だけ上書きできる
export const updated = { ...original, age: 21 };
// original はいっさい変わっていない
export const stillOriginal = original;この章のまとめ
const { name } = userは分割代入。 オブジェクトは名前、配列は順番で取り出すuseStateの[count, setCount]も、ただの配列の分割代入...は中身を展開する記号。あとに書いたものが勝つ- スプレッド構文は書き換えではなく新しく作るための道具。 React の state 更新はこの形で書く
spread.ts
const original = { name: "さとう", age: 20 };
// ... で中身を展開して、新しいオブジェクトを作る
export const copied = { ...original };
// 展開したあとに書けば、その項目だけ上書きできる
export const updated = { ...original, age: 21 };
// original はいっさい変わっていない
export const stillOriginal = original;