Part 0 · React の前に
4 / 64 章
配列の map
リスト表示のすべてがここから始まる
React の画面は、そのほとんどが「配列を並べたもの」でできています。 商品の一覧、コメント、検索結果、メニュー。 データの中身が違うだけで、やっていることは全部同じです。
そして React でそれを書くとき、必ず出てくるのが map です。
ここが曖昧なままだと、React のコードが一生読めません。 逆にここさえ押さえれば、リスト表示は全部同じ形に見えてきます。
map は「ひとつずつ作り変える」
map は配列のメソッド(=配列が最初から持っている関数)で、やることはひとつだけです。
map に渡しているのは関数です。前の章でやった 「関数を他の関数に渡す」が、さっそくここで出てきます。
元の配列は変わらず、新しい配列が返ってくる
- numbers(元の配列)
- [1, 2, 3]
- doubled(map の結果)
- [2, 4, 6]
注目してほしいのは、元の numbers が変わっていないことです。map は元の配列に手を加えません。 別の配列を新しく作って返すだけです。
「変数と const」の章で 「React では値を書き換えず、新しく作る」と書きました。map はまさにその考え方でできています。 React と相性がいいのはそのためです。
map-basic.ts
export const numbers = [1, 2, 3];
// ひとつずつ 2 倍にして、新しい配列を作る
export const doubled = numbers.map((n) => n * 2);オブジェクトの配列から取り出す
実際のデータは、たいていオブジェクトの配列です。 そこから必要なものだけを取り出したり、別の形に整えたりするのにも 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 の兄弟たち
map と同じ形で使える仲間がいます。この 3 つは、React でも map と同じくらい出てきます。いま覚えなくても構いませんが、何が返るかだけ見ておいてください。
返ってきたものの形に注目
scores = [1, 2, 3, 4, 5]
scores.map((n) => n * 2)[2,4,6,8,10]数は変わらないscores.filter((n) => n > 2)[3,4,5]数が減るscores.find((n) => n > 2)3配列ではないscores.reduce((sum, n) => sum + n, 0)151 つにまとまる
違いは「何が返るか」です。
map… 同じ数の配列。作り変えるfilter… 減った配列。選び出すfind… 配列ではなく 1 つの値。探すreduce… 1 つにまとめた値。畳む
どれも関数を受け取るという点で共通しています。 やはり「関数を値として渡せる」ことが土台になっています。
map-friends.ts
const scores = [1, 2, 3, 4, 5];
// map … 全部を作り変える。数は変わらない
export const doubled = scores.map((n) => n * 2); // [2, 4, 6, 8, 10]
// filter … 条件に合うものだけ残す。数が減る
export const big = scores.filter((n) => n > 2); // [3, 4, 5]
// find … 条件に合う最初の 1 つ。配列ではなく値が返る
export const firstBig = scores.find((n) => n > 2); // 3
// reduce … ひとつの値にまとめる。第 2 引数は始めの値
export const total = scores.reduce((sum, n) => sum + n, 0); // 15
// どれも元の配列は変えない
export const original = scores; // [1, 2, 3, 4, 5]理解できたか確かめる
確認クイズ
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);この章のまとめ
mapは、要素をひとつずつ関数に通して新しい配列を返す- 元の配列は変わらない
- 返ってくるものの中身は、渡した関数が何を返すかで決まる
- React では、関数が画面の部品を返すようにする。 これがリスト表示の正体
map-basic.ts
export const numbers = [1, 2, 3];
// ひとつずつ 2 倍にして、新しい配列を作る
export const doubled = numbers.map((n) => n * 2);