2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Recoil公式ドキュメント 翻訳⑦ 基本チュートリアル-Selectors

Last updated at Posted at 2020-10-20

Recoilの公式ドキュメントをgoogle翻訳するとコードまで翻訳されてしまうのが面倒なのでQiitaにまとめてみます。

追々追加していきます。(多分)

公式ドキュメント

目次

全目次は一番下にあります


Selector

selectorは、**derived state (派生状態)**を表します。派生stateは、与えられたstateを何らかの方法で変更する純粋な関数にstateを渡す出力と考えることができます。

派生stateは、他のデータに依存する動的データを構築できるため、強力な概念です。todoリストアプリケーションのコンテキストでは、次のものが派生stateと見なされます。

  • フィルタされたtodoリスト:いくつかの基準(すでに完了している項目を除外するなど)に基づいてフィルタされた特定の項目を持つ新しいリストを作成することによって、完全なtodoリストから派生します。
  • ToDoリストの統計:リスト内の項目の総数、完了した項目の数、完了した項目の割合など、リストの有用な属性を計算することによって、完全なToDoリストから得られます。

フィルタされたtodoリストを実装するには、atomに値を保存できる一連のフィルタ条件を選択する必要があります。
使用するフィルタオプションは、「すべて表示」、「完了を表示」、および「未完了を表示」です。デフォルト値は「すべて表示」です。

const todoListFilterState = atom({
  key: 'todoListFilterState',
  default: 'Show All',
});

todoListFilterStatetodoListStateを使用して、フィルタされたリストを導出するfilteredTodoListStateselectorを構築できます。

const filteredTodoListState = selector({
  key: 'filteredTodoListState',
  get: ({get}) => {
    const filter = get(todoListFilterState);
    const list = get(todoListState);

    switch (filter) {
      case 'Show Completed':
        return list.filter((item) => item.isComplete);
      case 'Show Uncompleted':
        return list.filter((item) => !item.isComplete);
      default:
        return list;
    }
  },
});

filteredTodoListStateは内部的に2つの依存関係 (todoListFilterStatetodoListState) を追跡し、どちらかが変更された場合に再実行されるようにします。

コンポーネントの観点から見ると、selectorは、atomを読み取るために使用されるのと同じhookを使用して読み取ることができます。ただし、一部のhookは書き込み可能なstate(i.e useRecoilState())でのみ機能することに注意してください。
全てのatomは書き込み可能stateであるが、書き込み可能stateとみなされるのは一部のselectorのみである(getプロパティとsetプロパティの両方を持つselector)。このトピックの詳細は、コアコンセプトを参照してください。

フィルタリングされたtodoListの表示は、TodoListコンポーネントで1行変更するだけです。

function TodoList() {
  // todoListState から filteredTodoListState に変更されました
  const todoList = useRecoilValue(filteredTodoListState);

  return (
    <>
      <TodoListStats />
      <TodoListFilters />
      <TodoItemCreator />

      {todoList.map((todoItem) => (
        <TodoItem item={todoItem} key={todoItem.id} />
      ))}
    </>
  );
}

todoListFilterStateにデフォルト値「すべて表示(Show All)」が指定されているため、UIはすべてのtodoを表示していることに注意してください。
フィルタを変更するには、TodoListFiltersコンポーネントを実装する必要があります。

function TodoListFilters() {
  const [filter, setFilter] = useRecoilState(todoListFilterState);

  const updateFilter = ({target: {value}}) => {
    setFilter(value);
  };

  return (
    <>
      Filter:
      <select value={filter} onChange={updateFilter}>
        <option value="Show All">All</option>
        <option value="Show Completed">Completed</option>
        <option value="Show Uncompleted">Uncompleted</option>
      </select>
    </>
  );
}

数行のコードでフィルタリングを実装することができました!
同じ概念を使用して、TodoListStatsコンポーネントを実装します。

次の統計を表示します。

  • todo項目の合計数
  • 完了項目の合計数
  • 未完了項目の合計数
  • 達成率

統計情報ごとにselectorを作成することもできますが、より簡単な方法は、必要なデータを含むオブジェクトを返すselectorを1つ作成することです。このselectorをdoListStatsStateと呼びます。

const todoListStatsState = selector({
  key: 'todoListStatsState',
  get: ({get}) => {
    const todoList = get(todoListState);
    const totalNum = todoList.length;
    const totalCompletedNum = todoList.filter((item) => item.isComplete).length;
    const totalUncompletedNum = totalNum - totalCompletedNum;
    const percentCompleted = totalNum === 0 ? 0 : totalCompletedNum / totalNum;

    return {
      totalNum,
      totalCompletedNum,
      totalUncompletedNum,
      percentCompleted,
    };
  },
});

todoListStatsStateの値を読み取るには、もう一度useRecoilValue()を使用します。

function TodoListStats() {
  const {
    totalNum,
    totalCompletedNum,
    totalUncompletedNum,
    percentCompleted,
  } = useRecoilValue(todoListStatsState);

  const formattedPercentCompleted = Math.round(percentCompleted * 100);

  return (
    <ul>
      <li>Total items: {totalNum}</li>
      <li>Items completed: {totalCompletedNum}</li>
      <li>Items not completed: {totalUncompletedNum}</li>
      <li>Percent completed: {formattedPercentCompleted}</li>
    </ul>
  );
}

まとめると、私たちはすべての要件を満たすtodoリストアプリを作成しました。

  • todo項目を追加する
  • todo項目を編集する
  • todo項目を削除する
  • todo項目をフィルタする
  • 有用な統計を表示

>>Demoを作りました


参考サイト

公式ドキュメント
みらい翻訳


全目次

2
1
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
2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?