使用 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>
);
}
```
我正在使用 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>
);
}
```