UserDucer:
用户播放器 是最受欢迎的钩子之一。 Usereducer 挂钩返回当前阶段和调度方法。它类似于美国挂钩。如果我们想制作复杂的逻辑,则用户用户可能非常有用。
如果要下载完整的演示项目,请单击此处。
句法:
useReducer(<reducer>, <initialState>)
useReducer(<reducer>, <initialState>, <init>)
在这里,还原器函数包含自定义状态逻辑,初始状态可以是示例默认状态值。
init 是一个函数,只要我们要懒惰地创建初始状态。
减速器:
a 还原器是能够处理用户指令/操作的函数。还原器通过用户操作处理现有状态,并返回 new State 。
下面我们将尝试制定一个简单的应用程序,以更好地理解。
TODO应用程序:
下图显示了我们应用程序的UI。
我们可以看到它包含一个提交按钮,如果我们保存它,则它将显示在列表中,我们可以完成并删除该物品。
我们将使我们的代码尽可能简单。
让我们尝试制作动作类型
在这里,我们将进行3种类型的动作,
- 添加todo
- 删除todo
- 完整的todo
我在 src 目录中创建了一个新文件夹,并且文件夹名称为 Action 。在该文件夹中,我创建了一个 index.js 文件并放置以下代码。
// src/action/index.js
export const ADD_TODO = "ADD_TODO";
export const REMOVE_TODO = "REMOVE_TODO";
export const COMPLETE_TODO = "COMPLETE_TODO";
我们为用户创建了三个常数操作类型。
让我们尝试制作还原
我们已经知道还原器基本上是一个包含复杂逻辑的函数。我们需要传递价值和指令/行动,然后将以前的状态更改为新状态。就像 redux 一样,但我们不需要在这里初始化还原器。
我创建了一个新文件夹并将其命名为reducer,在该文件夹中,我创建了一个index.js文件并放置了以下代码,
import { ADD_TODO, REMOVE_TODO, COMPLETE_TODO } from './../action'
const reducer = (state, action) => {
switch (action.type) {
case ADD_TODO:
const newTodo = {
id: action.id,
text: action.text,
completed: false
};
return [...state, newTodo];
case REMOVE_TODO:
return state.filter((todo) => todo.id !== action.id);
case COMPLETE_TODO:
const completeTodo = state.map((todo) => {
if (todo.id === action.id) {
return {
...todo,
completed: !todo.completed
};
} else {
return todo;
}
});
return completeTodo;
default:
return state;
}
};
export default reducer;
在还原器功能中,我们使用了 switch 语句来检查用户操作。如果用户想添加新的todo ,则操作类型将为 add_todo 并基于开关语句,它将执行 add_todo 逻辑在该块中。最后,它将返回新状态。
case ADD_TODO:
const newTodo = {
id: action.id,
text: action.text,
completed: false
};
return [...state, newTodo];
to 删除 todo任务,操作类型将为 remove_todo ,并基于 switch _语句,它将执行_remove_todo 逻辑在那个块中。最后,它将返回到 new State 。
case REMOVE_TODO:
return state.filter((todo) => todo.id !== action.id);
to 完整 a todo ,操作将为 pouttion_todo ,它将执行他的逻辑并返回新状态。
case COMPLETE_TODO:
const completeTodo = state.map((todo) => {
if (todo.id === action.id) {
return {
...todo,
completed: !todo.completed
};
} else {
return todo;
}
});
return completeTodo;
这是一个简单的示例,所以我还没有将 ui 分为单独的容器。我将所有内容都放在 app.js 文件中。
让将UserDucer 放在app.js
中
import { useReducer, useState } from "react";
import "./index.css";
import reducer from "./reducer";
import { ADD_TODO, REMOVE_TODO, COMPLETE_TODO } from './action'
export default function App() {
const [id, setId] = useState(0);
const [text, setText] = useState("");
const initialState = [
{
id: id,
text: "First todo Item",
completed: false
}
];
//We could also pass an empty array as the initial state
//const initialState = []
const [state, dispatch] = useReducer(reducer, initialState);
const addTodoItem = (e) => {
e.preventDefault();
const newId = id + 1;
setId(newId);
dispatch({
type: ADD_TODO,
id: newId,
text: text
});
setText("");
};
const removeTodo = (id) => {
dispatch({ type: REMOVE_TODO, id });
};
const completeTodo = (id) => {
dispatch({ type: COMPLETE_TODO, id });
};
return (
<div className="App">
<h2>Todo Example</h2>
<form className="input" onSubmit={addTodoItem}>
<input value={text} onChange={(e) => setText(e.target.value)} />
<button disabled={text.length === 0} type="submit">+</button>
</form>
<div className="todos">
{state.map((todo) => (
<div key={todo.id} className="todoItem">
<p className="">{todo.completed ? <del>{todo.text}</del> : todo.text}</p>
<div className="actionType">
<span onClick={() => removeTodo(todo.id)}>✕</span>
<span onClick={() => completeTodo(todo.id)}>✓</span>
</div>
</div>
))}
</div>
</div>
);
}
在上面的代码中,我们可以看到用户eDucer 将 reducer函数和 initialstate 作为参数然后它返回 state 和 dispatch 。
当某人键入某些 text 并单击+ sign 时,则在 addtodoitem 函数 dispatch函数被称为并包含 3参数这些是 type(add_todo), id 和 text 。调度将触发还原器函数,并基于 type 还原器函数将添加一个新的todo项目,返回新状态。
dispatch({
type: ADD_TODO,
id: newId,
text: text
});
当某人单击 时,将调用另一个调度函数,此时间类型将为 remove_todo ,并基于 type 和 id ,降低器函数 emoves emoves 返回新状态。
dispatch({ type: REMOVE_TODO, id });
当某人单击时, dispatch函数将触发使用动作类型 pountty_todo 触发降低器降低器,然后还原器Will Update 基于 id 的对象和返回 new State 。
dispatch({ type: COMPLETE_TODO, id });
让我们将一些 css 放在 index.css 文件中,
body {
margin: 0;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
code {
font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
monospace;
}
.App {
width: 205px;
margin: auto;
}
.todoItem {
width: 100%;
float: left;
border-bottom: 1px solid;
}
.todoItem p {
float: left;
}
.actionType {
float: right;
margin-top: 15px;
}
如果要下载完整的演示项目,请单击此处。
这就是今天的全部,接下来,我们将了解React usecontext hook以及如何与用户使用一起使用。
见ya。