使用 useReducer 在点击时反应显示过滤状态

React show filtered state on click with useReducer

我正在使用 React 构建 Todo 应用程序,几乎一切正常。待办事项有一个“已完成”属性,基于属性我想过滤待办事项。 (当您单击某个项目时,“已完成”属性 从 false 变为 true )。

This就是这个样子。 但我有点不知道如何实现它。


const ACTIONS = {
  ADD_TODO: "add-todo",
  CLEAR_TODO: "clear-todo",
  SWITCH_TODO_TYPE: "switch-todo-type",
};

const todosInitalState = {
  todos: [
   {todoValue: "exampleTodo", id: 3.14, completed: false},
   {todoValue: "exampleTodoNo2", id: 42, completed: true}
  ],
  activeTodos: [
   {todoValue: "exampleTodo", id: 3.14, completed: false},
  ],
  completedTodos: [
   {todoValue: "exampleTodoNo2", id: 42, completed: true}
  ],
};
export default function TodosState() {
  const [todosState, dispatchTodos] = useReducer(
    todosReducer,
    todosInitalState
  );

  const uncheckedTodos = todosState.todos.filter(
    (todo) => todo.completed === false
  );

  return (
    <div className={styles["todos-container"]}>
      <h1>Todo</h1>
      <Input onAddTodo={storeTodoValue}></Input>
      <ul>
        {todosState.todos.map((todo) => { // `**HOW CAN I NOW SHOW THE STATE BASED ON THE CLICKED BUTTON** `
          return (
            <TodoItem
              key={todo.id}
              id={todo.id}
              text={todo.todoValue}
              onCheck={saveCheckedValues}
            ></TodoItem>
          );
        })}
      </ul>
      <div className={styles["todos-container__bottom"]}>
        <span>{uncheckedTodos.length} tasks left</span>
        <div className={styles.buttons}>
          <button>All</button>
          <button>Active</button>
          <button>Completed</button>
        </div>
        <button onClick={deleteCheckedTodos}>Clear Completed</button>
      </div>
    </div>
  );
}

我已经完成了过滤逻辑。所以这只是关于我如何根据按钮呈现正确的状态。有什么技巧可以实现吗? :)

您可以定义辅助 filteredTodo 状态来存储过滤后的待办事项。
然后,声明一个filterTodos函数来根据点击的按钮过滤列表:

const ACTIONS = {
  ADD_TODO: 'add-todo',
  CLEAR_TODO: 'clear-todo',
  SWITCH_TODO_TYPE: 'switch-todo-type',
};

const todosInitalState = {
  todos: [
    { todoValue: 'exampleTodo', id: 3.14, completed: false },
    { todoValue: 'exampleTodoNo2', id: 42, completed: true },
  ],
  activeTodos: [{ todoValue: 'exampleTodo', id: 3.14, completed: false }],
  completedTodos: [{ todoValue: 'exampleTodoNo2', id: 42, completed: true }],
};
export default function TodosState() {
  const [todosState, dispatchTodos] = useReducer(
    todosReducer,
    todosInitalState
  );

  const uncheckedTodos = todosState.todos.filter(
    (todo) => todo.completed === false
  );

  const filterTodos = (state) => {
    switch (state) {
      case 'All':
        setFilteredTodo([...todosState.todos]);
        break;
      case 'Active':
        setFilteredTodo(
          [...todosState.todos].filter((todo) => todo.completed === false)
        );
        break;
      case 'Completed':
        setFilteredTodo(
          [...todosState.todos].filter((todo) => todo.completed === true)
        );
        break;
      default:
        break;
    }
  };

  const [filteredTodo, setFilteredTodo] = useState([...todosState.todos]);

  return (
    <div className={styles['todos-container']}>
      <h1>Todo</h1>
      <Input onAddTodo={storeTodoValue}></Input>
      <ul>
        {filteredTodo.map((todo) => {
          return (
            <TodoItem
              key={todo.id}
              id={todo.id}
              text={todo.todoValue}
              onCheck={saveCheckedValues}
            ></TodoItem>
          );
        })}
      </ul>
      <div className={styles['todos-container__bottom']}>
        <span>{uncheckedTodos.length} tasks left</span>
        <div className={styles.buttons}>
          <button onClick={() => filterTodos('All')}>All</button>
          <button onClick={() => filterTodos('Active')}>Active</button>
          <button onClick={() => filterTodos('Completed')}>Completed</button>
        </div>
        <button onClick={deleteCheckedTodos}>Clear Completed</button>
      </div>
    </div>
  );
}
```