Part 0 · React の前に
配列の map
リスト表示のすべてがここから始まる
React の画面は、そのほとんどが「配列を並べたもの」でできています。 商品の一覧、コメント、検索結果、メニュー。 データの中身が違うだけで、やっていることは全部同じです。
そして React でそれを書くとき、必ず出てくるのが map です。
ここが曖昧なままだと、React のコードが一生読めません。 逆にここさえ押さえれば、リスト表示は全部同じ形に見えてきます。
map は「ひとつずつ作り変える」
map は配列のメソッドで、やることはひとつだけです。
map に渡しているのは関数です。前の章でやった 「関数を他の関数に渡す」が、さっそくここで出てきます。
元の配列は変わらず、新しい配列が返ってくる
- numbers(元の配列)
- [1, 2, 3]
- doubled(map の結果)
- [2, 4, 6]
注目してほしいのは、元の numbers が変わっていないことです。map は元の配列に手を加えません。 別の配列を新しく作って返すだけです。
前の章で「React では値を書き換えず、新しく作る」と書きました。map はまさにその考え方でできています。 React と相性がいいのはそのためです。
map-basic.ts
export const numbers = [1, 2, 3];
// ひとつずつ 2 倍にして、新しい配列を作る
export const doubled = numbers.map((n) => n * 2);
// numbers 自体はいっさい変わっていないオブジェクトの配列から取り出す
実際のデータは、たいていオブジェクトの配列です。 そこから必要なものだけを取り出したり、別の形に整えたりするのにも map を使います。
渡す関数を変えれば、作られるものも変わる
- names
- ["さとう", "すずき", "たかはし"]
- labels
- ["さとう(20)", "すずき(25)", "たかはし(30)"]
map が返すものは、渡した関数が何を返すかで決まります。 数値を返せば数値の配列、文字列を返せば文字列の配列になります。
map-object.ts
const members = [
{ id: 1, name: "さとう", age: 20 },
{ id: 2, name: "すずき", age: 25 },
{ id: 3, name: "たかはし", age: 30 },
];
// オブジェクトの配列から、名前だけを取り出す
export const names = members.map((member) => member.name);
// 別の形に作り変えることもできる
export const labels = members.map((member) => `${member.name}(${member.age})`);React では JSX を返す
ここまでくれば、React のリスト表示はもう読めます。 返すものを画面の部品にするだけです。
{members.map((member) => (
<li key={member.id}>{member.name}</li>
))}map が返しているのは「画面の部品が入った配列」です。React はそれを受け取って、順番に並べて表示します。
for 文を書いて 1 行ずつ追加していく、という手順は登場しません。 「この配列を、この形に変えたものを表示したい」と書くだけです。
map-object.ts
const members = [
{ id: 1, name: "さとう", age: 20 },
{ id: 2, name: "すずき", age: 25 },
{ id: 3, name: "たかはし", age: 30 },
];
// オブジェクトの配列から、名前だけを取り出す
export const names = members.map((member) => member.name);
// 別の形に作り変えることもできる
export const labels = members.map((member) => `${member.name}(${member.age})`);ついでに覚えておくと便利なもの
map と同じ形で使える仲間がいます。 いま完璧に覚える必要はありませんが、名前だけ知っておくと読むときに困りません。
const numbers = [1, 2, 3, 4, 5];
// 条件に合うものだけ残す
numbers.filter((n) => n > 2); // [3, 4, 5]
// 条件に合う最初の 1 つを探す
numbers.find((n) => n > 2); // 3
// ひとつの値にまとめる
numbers.reduce((sum, n) => sum + n, 0); // 15どれも関数を受け取るという点で共通しています。 やはり「関数を値として渡せる」ことが土台になっています。
map-basic.ts
export const numbers = [1, 2, 3];
// ひとつずつ 2 倍にして、新しい配列を作る
export const doubled = numbers.map((n) => n * 2);
// numbers 自体はいっさい変わっていない理解できたか確かめる
確認クイズ
const doubled = numbers.map((n) => n * 2); を実行したあと、numbers はどうなっている?
確認クイズ
members.map((member) => member.name) が返すのは?
map-basic.ts
export const numbers = [1, 2, 3];
// ひとつずつ 2 倍にして、新しい配列を作る
export const doubled = numbers.map((n) => n * 2);
// numbers 自体はいっさい変わっていないこの章のまとめ
mapは、要素をひとつずつ関数に通して新しい配列を返す- 元の配列は変わらない
- 返ってくるものの中身は、渡した関数が何を返すかで決まる
- React では、関数が画面の部品を返すようにする。 これがリスト表示の正体
map-basic.ts
export const numbers = [1, 2, 3];
// ひとつずつ 2 倍にして、新しい配列を作る
export const doubled = numbers.map((n) => n * 2);
// numbers 自体はいっさい変わっていない