filterメソッドを使ってみよう
プロ太先生、filter
って何ですか?配列の中身を絞り込むって聞いたことがあるんですが…。
filter
は配列の中から条件に合った要素だけを取り出すためのメソッドですね。たとえば、リストの中で特定の文字が含まれているものだけを表示したいときに使えるんです。こんなコードを書いてみましょう。フィルターで動物の名前を絞り込む例です。
コード例1:動物リストをフィルターする
import { useState } from "react";
const animals = ["Tiger", "Lion", "Elephant"];
// POINT filterメソッドの使い方
const Example = () => {
const [filterVal, setFilterVal] = useState("");
return (
<>
<h3>配列のフィルター</h3>
<input
type="text"
value={filterVal}
onChange={(e) => setFilterVal(e.target.value)}
placeholder="動物の名前を入力してみてね"
/>
<ul>
{animals
.filter((animal) => animal.includes(filterVal))
.map((animal) => (
<li key={animal}>{animal}</li>
))}
</ul>
</>
);
};
export default Example;
まずは、useState
を使ってfilterVal
という値を管理しています。このfilterVal
には、OZくんがテキストボックスに入力した値が常にセットされるんです。
なるほど、テキストボックスで入力した内容がそのままfilterVal
に入るんですね。
そうです。そして、animals.filter()
を使って、各要素に対してfilterVal
が含まれているかどうかを確認しています。
{animals
.filter((animal) => animal.includes(filterVal))
の部分では、animalsの配列に対して、includes
メソッドを使って、filterVal
がその配列の要素に含まれているかチェックしているんですね。
その通りです!そして、フィルターされた結果がmap
メソッドでリストとして表示されるわけだね。じゃあ、ちょっと実行して、テキストボックスに『Ti』とか入力してみてくれる?
はい、やってみます!…おお、Tiger
だけが出てきました!
次に、もう少し複雑なデータのフィルターを試してみましょう。今回は人のプロフィールをフィルターします。
import Profile from "./components/Profile";
import { useState } from "react";
const persons = [
{
name: "Alex",
age: 20,
hobbies: ["swimming", "reading"],
},
{
name: "Bella",
age: 25,
hobbies: ["cooking", "painting"],
},
{
name: "Chris",
age: 18,
hobbies: ["gaming", "music", "hiking"],
},
];
const Example = () => {
const [filterVal, setFilterVal] = useState("");
return (
<>
<input
type="text"
value={filterVal}
onChange={(e) => setFilterVal(e.target.value)}
placeholder="名前を入力してみてね"
/>
<ul>
{persons
.filter((person) => person.name.includes(filterVal))
.map((person) => (
<li key={person.name}>
<Profile {...person} />
</li>
))}
</ul>
</>
);
};
export default Sample;
このProfile
コンポーネントは何をしているんですか?
このProfile
コンポーネントが人物のプロフィールを表示してくれるんです。詳細をコードで確認してみましょう。
const Profile = ({ name, age, hobbies }) => {
return (
<div>
<hr />
<div>名前: {name}</div>
<div>年齢: {age}</div>
<div>
<div>趣味:</div>
<ul>
{hobbies.map((hobby) => (
<li key={hobby}>{hobby}</li>
))}
</ul>
</div>
</div>
);
};
export default Profile;
それじゃあ、まず、Sample.jsxファイルの、人物リストpersons
のフィルター部分を詳しく解説していきますね。以下の部分です。filterメソッドについては解説済みですが、復習しておきましょう!
<ul>
{persons
.filter((person) => person.name.includes(filterVal))
.map((person) => (
<li key={person.name}>
<Profile {...person} />
</li>
))}
</ul>
コード解説
persons.filter()
の部分:filter
メソッドは配列persons
の各要素(ここではperson
)を順にチェックして、特定の条件に合う要素だけを新しい配列にまとめます。- 条件としては、
person.name.includes(filterVal)
がtrue
のときだけそのperson
をフィルター結果に含めます。 includes
メソッドは、文字列の中に指定した文字が含まれているかを確認します。この場合、filterVal
の文字がperson.name
に含まれているかどうかをチェックしています。
map
メソッドでリストを表示:- フィルターで条件に合った人物の配列を得た後、その配列の各要素を
<li>
タグでリスト表示します。 person
のデータをProfile
コンポーネントに渡して表示するために、<Profile {...person} />
と書かれています。これはスプレッド構文を使って、person
オブジェクトの中身をProfile
コンポーネントに渡しています。
この{...person}
は、person
オブジェクトの中にあるすべてのプロパティ(例えば、name
、age
、hobbies
)を展開して、それぞれをProfile
に一括で渡すという意味です。これで、Profile
コンポーネントの中では、name
、age
、hobbies
が個別のプロパティとして扱えるようになります。スプレッド構文を使わずに一つずつ渡すとしたら、以下のような感じになります。
- フィルターで条件に合った人物の配列を得た後、その配列の各要素を
<Profile name={person.name} age={person.age} hobbies={person.hobbies} />
person
オブジェクトにさらにaddress
やjob
といった新しいプロパティが追加された場合、それぞれを追加で書き込む必要が出てきますが、スプレッド構文を使えば、オブジェクトの中身をまとめて展開できるから便利です。
3.key
属性の追加:
- Reactでは、リスト表示を行うときに
key
属性を指定することが推奨されています。ここでは、key={person.name}
として、各人物のname
をkey
に使っています。 key
はReactが各要素を識別するためのものなので、重複しない値(ユニークな値)である必要があります。
なるほど!filter
とmap
が連携して、入力した名前に応じた人物だけがリストに表示されるんですね。
その通り!そして、Profile
コンポーネントに人物のデータを渡して、個別に表示するようにしているんです。
次に気になるのがhobbies
の部分です。趣味のリストがどうやって表示されるのか教えてください!以下の部分です。
<ul>
{hobbies.map((hobby) => (
<li key={hobby}>{hobby}</li>
))}
</ul>
コード解説
map
メソッド:map
メソッドは配列の各要素を順に処理し、処理結果を新しい配列として返します。この場合、hobbies
配列の各hobby
をリスト形式で表示しています。hobbies.map((hobby) => ( ... ))
では、hobby
がhobbies
配列の各要素を順番に受け取って処理します。
<li key={hobby}>{hobby}</li>
タグ:<li>
タグの中に各hobby
の内容が表示されます。これにより、趣味がリスト形式で一つずつ表示されるようになります。key
属性にはhobby
自体を指定しています。hobby
がユニークであることが前提ですが、同じ趣味が含まれる場合には異なるキーを用意するか、他の値を使うことを検討する必要があります。
map
を使うことで配列の各要素を一つずつ表示できるんですね!これで趣味がリストとして表示されるわけですね。
その通り!そして、Profile
コンポーネントの中では、hobbies
という配列を受け取って、趣味を一覧表示しているんだ。このようにコンポーネントの中でmap
を使えば、配列データを簡単にリスト表示できるようになりますよ!
補足:filterメソッド第2引数・第3引数のReactでの使い方
filter メソッドの第2引数に渡すのは、各要素に対して呼び出されるコールバック関数 です。このコールバック関数は、以下の3つの引数を取ることができます。
- element: 現在の配列要素
- index: 現在の要素のインデックス
- array: 配列全体
つまり、上記3つのどれかでしぼっていくことができるということです!!
コールバック関数の役割
コールバック関数は、各要素に対して実行され、その戻り値が true
の場合に、その要素が新しい配列に含まれます。つまり、条件を満たす要素だけを抽出する 働きをします。
第1引数の活用例
const numbers = [1, 2, 3, 4, 5];
// 偶数のみを抽出
const evenNumbers = numbers.filter(function(element) {
return element % 2 === 0;
});
console.log(evenNumbers); // [2, 4]
この例では、filter
メソッドのコールバック関数で、要素が偶数かどうかを判定しています。偶数の場合に true
を返し、新しい配列 evenNumbers
に追加されます。
第2引数の活用例
const words = ['apple', 'banana', 'cherry', 'date'];
// インデックスが偶数の要素のみを抽出
const evenIndexWords = words.filter((_, index) => {
return index % 2 === 0;
});
console.log(evenIndexWords); // ['apple', 'cherry']
この例では、_
で要素の値は無視し、index
を使ってインデックスが偶数の要素だけを抽出しています。
第3引数 (array) の活用例
const numbers = [1, 2, 3, 2, 1];
// 重複する要素を除去
const uniqueNumbers = numbers.filter((element, index, array) => {
return array.indexOf(element) === index;
});
console.log(uniqueNumbers); // [1, 2, 3]
この例では、array.indexOf(element)
で、要素が初めて現れるインデックスを取得し、それが現在のインデックスと一致する場合にのみ、その要素を新しい配列に追加しています。これにより、重複する要素を除去することができます。
まとめ
今日の授業内容で、配列のフィルターと表示のやり方が分かりました!実際にコードを書きながらやってみます!
それが一番ですね!Reactの基本操作は慣れると応用が効くから、どんどん試してみましょう!
このように、リストのフィルターと配列の表示を学ぶことで、データを動的に管理し表示する方法を理解できたかと思います。さらに実践で応用しながら身に着けていきましょう!