React показывает отфильтрованное состояние при нажатии с помощью useReducer

Я создаю приложение Todo с помощью React, и почти все работает нормально. У задач есть «завершено» свойство и на основе свойства я хочу отфильтровать задачи. (Когда вы нажимаете на элемент, свойство «завершено» меняется с false на true).

Этот — вот как это выглядит. Но я как-то не знаю, как это реализовать.


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>
  );
}

Я уже сделал логику фильтра. Так что это просто о том, как я могу отобразить правильное состояние на основе кнопки. Любые советы, как я могу этого добиться? :)

Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Навигация по приложениям React: Исчерпывающее руководство по React Router
Навигация по приложениям React: Исчерпывающее руководство по React Router
React Router стала незаменимой библиотекой для создания одностраничных приложений с навигацией в React. В этой статье блога мы подробно рассмотрим...
Массив зависимостей в React
Массив зависимостей в React
Все о массиве Dependency и его связи с useEffect.
1
0
29
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вы можете определить вспомогательное 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>
  );
}
```

Я имею в виду, что это работает, но теперь мои задачи загружаются только при нажатии на кнопки, а не при перезагрузке страницы. Но все равно спасибо :)

PSM-Ayhan 19.03.2022 21:36

Другие вопросы по теме