TL;DR
このページでは、Next.js で頻出する、JavaScript の map() メソッドの実装方法について解説します。Next.js と TypeScript の環境で、どのように map() メソッドを用いてデータのループ処理が行えるか、その具体的な例とその解説を行います。
開発環境 | バージョン |
---|---|
Next.js | 13.4.3 |
TypeScript | 5.0.4 |
Emotion | 11.11.0 |
React | 18.2.0 |
map() メソッドとは?
JavaScript の Array のメソッドである map() は、配列の各要素に対して関数を適用し、その結果から新しい配列を作成します。React の JSX 内でよく用いられ、配列のデータを要素として描画するのに適しています。
例えば、次のように書くことができます。
const numbers = [1, 2, 3, 4, 5]
const doubled = numbers.map((number) => number * 2)
console.log(doubled) // [2, 4, 6, 8, 10]
Next.js で、map() メソッドを実装
ファイル名: components/NumberList.tsx
type Props = {
numbers: number[]
}
const NumberList = ({ numbers }: Props) => {
return (
<ul>
{numbers.map((number) => (
<li key={number}>{number}</li>
))}
</ul>
)
}
export default NumberList
このコンポーネントは、受け取った numbers
配列をリスト要素としてレンダリングします。map()
メソッドが numbers
の各要素に対して実行され、各要素がリストアイテム <li>
としてレンダリングされます。
ここで重要なのは、各リストアイテムに一意な key
prop を与えることです。これは React がどのアイテムを変更、追加、削除するかを識別するために必要です。
map() メソッドを実装
Next.js のページコンポーネントでこの NumberList
コンポーネントを使う例を見てみましょう。
ファイル名: pages/index.tsx
import NumberList from '../components/NumberList'
const Home = () => {
const numbers = [1, 2, 3, 4, 5]
return (
<div>
<h1>Hello Next.js</h1>
<NumberList numbers={numbers} />
</div>
)
}
export default Home
ここでは numbers
という配列を NumberList
コンポーネントに渡しています。すると、NumberList
内部で map() メソッドが適用され、各数字がリスト要素としてレンダリングされます。
Emotion で実装
Emotion を使って、各リストアイテムにスタイルを適用することも可能です。例えば、偶数のアイテムと奇数のアイテムで色を変えるといったこともできます。
ファイル名: components/StylishNumberList.tsx
/** @jsxImportSource @emotion/react */
import { css } from '@emotion/react'
import { FC } from 'react'
type Props = {
numbers: number[]
}
const StylishNumberList: FC<Props> = ({ numbers }) => {
return (
<ul>
{numbers.map((number) => (
<li
key={number}
css={css`
color: ${number % 2 === 0 ? 'blue' : 'red'};
`}
>
{number}
</li>
))}
</ul>
)
}
export default StylishNumberList
このコンポーネントは、各リストアイテムに css
prop を与えてスタイルを適用しています。数字が偶数なら青色、奇数なら赤色となるようにしています。このように Emotion を使えば、動的なスタイルも簡単に適用することができますね。
map(), forEach(), for...of の違い
JavaScript には、配列やイテラブルなオブジェクトをループ処理するための複数のメソッドや構文が存在します。ここでは、map()
, forEach()
, for...of
の 3 つについて考えてみましょう。
map()
map メソッドは配列のすべての要素に対して関数を実行し、その結果を新しい配列として返します。このメソッドは元の配列を変更せず、新しい配列を作成します。また、配列内の未定義の要素に対しては関数を実行しません。
forEach()
forEach メソッドは配列の各要素に対して関数を実行しますが、新しい配列を返しません。このメソッドは配列を直接変更することが可能です。forEach()
の使用例を以下に示します。例えば、次のように配列のすべての要素を二倍にする新しい配列を作成することができます。
forEach()
は元の配列を変更することが可能です。次の例では、各要素に対して特定の処理(ここでは console.log)を実行しています。
const fruits = ['apple', 'banana', 'cherry']
fruits.forEach((fruit, index) => {
console.log(`Fruit ${index + 1}: ${fruit}`)
})
// "Fruit 1: apple"
// "Fruit 2: banana"
// "Fruit 3: cherry"
上記の例では、forEach()
メソッドが配列 fruits
の各要素に対して引数の関数を実行しています。引数の関数は、要素の値とそのインデックスを取り、それぞれの要素に対して console.log を実行しています。
for...of
for...of 構文は配列やイテラブルなオブジェクト(例えば Map、Set、arguments オブジェクトなど)の要素を一つずつ取り出して処理を行います。これは特定の関数を適用するわけではなく、任意の処理をループ内で行うことができます。
メソッド / 構文 | 新しい配列を返す | 配列を直接変更 | 適用対象 |
---|---|---|---|
map() | はい | いいえ | 配列 |
forEach() | いいえ | 可能 | 配列 |
for...of | いいえ | 可能 | イテラブルなオブジェクト |
したがって、これらのメソッドや構文の選択は、目的や処理内容によって決まるでしょう。配列から新しい配列を生成する場合は map()
を、元の配列を変更する処理や返り値が不要な場合は forEach()
を、イテラブルなオブジェクトを扱う場合や任意の処理をループ内で行いたい場合は for...of
を選択します。