Chapter 08

Todoフィルターを追加する

shitakemura
shitakemura
2022.02.12に更新

はじめに

本チャプターでは フロントエンドアプリに Todo のフィルター機能を追加します。

TodoFilter コンポーネントを作成する

TodoFIlter コンポーネントを作成し、ALL / COMPLETED / NOT COMPLETED でフィルタリングできるようにします。

./frontend/components/Todo/TodoScreen.tsx
- import { useState } from "react";
+ import { useMemo, useState } from "react";
+ import { TodoFilter } from "./TodoFilter";

+ export const FILTER_VALUES = ["ALL", "COMPLETED", "NOT COMPLETED"] as const;
+ type FilterTupel = typeof FILTER_VALUES;
+ export type Filter = FilterTupel[number];

export const TodoScreen = () => {
  const { data } = useGetTodosQuery();
+ const [filter, setFilter] = useState<Filter>("ALL");

+ const todos = useMemo(() => {
+   if (!data) return [];

+   switch (filter) {
+     case "ALL":
+       return data.getTodos;
+     case "COMPLETED":
+       return data.getTodos.filter((todo) => todo.completed);
+     case "NOT COMPLETED":
+       return data.getTodos.filter((todo) => !todo.completed);
+   }
+ }, [data, filter]);

  return (
    <VStack w='full' spacing={10} paddingX={48} paddingY={16}>
      <TodoInput />
+     <TodoFilter filter={filter} setFilter={setFilter} />
-     <TodoList todos={data?.getTodos ?? []} />
+     <TodoList todos={todos} />
    </VStack>
  );
};
./frontend/components/Todo/TodoFilter.tsx
import { HStack, Button } from "@chakra-ui/react";
import { FILTER_VALUES } from ".";
import { Filter } from "./TodoScreen";

type TodoFilterProps = {
  filter: Filter;
  setFilter: (filter: Filter) => void;
};

export const TodoFilter = ({ filter, setFilter }: TodoFilterProps) => {
  return (
    <HStack spacing={4}>
      {FILTER_VALUES.map((filterValue) => (
        <Button
          key={filterValue}
          colorScheme={filter === filterValue ? "blue" : undefined}
          color={filter === filterValue ? "white" : undefined}
          onClick={() => setFilter(filterValue)}>
          {filterValue}
        </Button>
      ))}
    </HStack>
  );
};

npm run devを実行して動作を確認します。

以上で Todo フィルターの追加は完了です。