0
0

初サイト制作メモ6: useStateとuseMemoを使ってフィルタ機能を実装

Posted at

ラーメンのレビューを、条件で絞り込みたい。
スクリーンショット 2024-06-23 14.26.34.png

useStateとuseMemoを使って実現した。

  • useState
    • フィルタ条件となる、店名、メニュー、評価の変数を管理する
    • 入力欄の内容が変わった時、それを検知して値を更新・保持するように実装する
  • useMemo
    • useStateで管理している値に変更があった時「のみ」、フィルタを再計算する。余計な計算が走らなくて済む
      • 再計算のトリガーとする値は、useMemoの記述の末尾に、[]内で指定
index.tsx
const [nameFilter, setNameFilter] = useState("");
const [menuFilter, setMenuFilter] = useState("");
const [repeatFilter, setRepeatFilter] = useState<RepeatPreference | "">("");
const [modalIsOpen, setModalIsOpen] = useState(false);
const [selectedImage, setSelectedImage] = useState<string | null>(null);

const filteredRamen = useMemo(
() =>
  ramenList.filter((ramen) => {
    const matchesName = ramen.name
      .toLowerCase()
      .includes(nameFilter.toLowerCase());
    const matchesMenu = ramen.menu
      .toLowerCase()
      .includes(menuFilter.toLowerCase());
    const matchesRepeat = repeatFilter
      ? ramen.repeat === repeatFilter
      : true;
    return matchesName && matchesMenu && matchesRepeat;
  }),
[ramenList, nameFilter, menuFilter, repeatFilter]
);

フィルタ条件を入力するテキストボックス例は以下。

index.tsx
<input
  type="text"
  value={nameFilter}
  onChange={(e) => setNameFilter(e.target.value)}
  className="block w-full p-1 border rounded shadow-sm focus:ring-2 focus:ring-blue-500"
  placeholder="店名"
/>

フィルタ条件に入力すると、リアルタイムにフィルタしてくれるようになった!スクリーンショット 2024-06-23 14.34.13.png

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0