In a recent blog we showed how to build the demo app pictured below using functional components with React Hooks- useState. The demo app takes a student name and grade as inputs, and appends the inputs to a list.
在最近的博客中,我们展示了如何使用带有React Hooks- useState的功能组件来构建下图所示的演示应用程序。 演示应用程序将学生姓名和成绩作为输入,并将输入附加到列表中。
![Image for post](https://i-blog.csdnimg.cn/blog_migrate/bb5f3d6a84079ea15088f631e1574b10.png)
The components tree of the demo app is showed below. The app has two child components; FunctionForm
and StudentContainer
. Student
is a child component of StudentContainer
演示应用程序的组件树如下所示。 该应用程序包含两个子组件; FunctionForm
和StudentContainer
。 Student
是StudentContainer
的子组件
![Image for post](https://i-blog.csdnimg.cn/blog_migrate/f8ef46aaf19c72f151c26ac4cd4cbd6d.png)
多次使用状态 (multiple useState)
We used useState to pass in the original list/data to the
App
component我们使用useState将原始列表/数据传递给
App
组件We used useState to managed state in the
FunctionForm
component via controlled form.我们使用useState通过受控形式在
FunctionForm
组件中管理状态。We used useState to handle form submission and to add input data from the form to existing list.
我们使用useState来处理表单提交,并将表单中的输入数据添加到现有列表中。
In this blog, we useReducer to managed state instead of using multiple useState mentioned in the list above.
在此博客中,我们使用Reducer来管理状态,而不是使用多个useState 在上面的列表中提到。
[
useReducer
is ] An alternative touseState
. [useReducer
] Accepts a reducer of type(state, action) => newState
, and returns the current state paired with adispatch
method. (If you’re familiar with Redux, you already know how this works.)[
useReducer
是useReducer
的替代useState
。 [useReducer
]接受类型为(state, action) => newState
,并返回与dispatch
方法配对的当前状态。 (如果您熟悉Redux,则已经知道它的工作原理。)
useReducer
is usually preferable touseState
when you have complex state logic that involves multiple sub-values or when the next state depends on the previous one.当您具有涉及多个子值的复杂状态逻辑时,或者当下一个状态取决于上一个状态时,
useReducer
通常比useState
更可取。
In the following sections, we show how to replace each useState with a reducer type paired with a dispatch method. But first, here is what the App
component and reducer function looks like;
在以下各节中,我们显示如何用与调度方法配对的reducer类型替换每个useState 。 但是首先,这是App
组件和reducer函数的外观;
应用程序组件 (app component)
In this component, the useReducer takes an initialState const initialState={students: [], name: "", grade: ""}
and a reducer type, paired with a dispatch method and returns the variable’s current state — students, name, grade
在此组件中, useReducer接受initialState const initialState={students: [], name: "", grade: ""}
和一个reducer类型,与一个调度方法配对,并返回变量的当前状态- 学生 , 名称 , 成绩
The application state is in the App
component. We pass down callback function and pertinent state variables to FunctionForm
component to remotely managed state from the App
component. The students variable is passed to the studentsContainer, where each student is passed down to the student component.
应用程序状态在App
组件中。 我们将回调函数和相关状态变量传递给FunctionForm
组件,以从App
组件进行远程管理状态。 学生变量将被传递到studentsContainer,每个学生都将被向下传递给Student组件。
减速器功能 (reducer function)
The reducer function handles three action cases; “addData”, “inputField” and “addOneStudent” for loading data, controlled form and form submission respectively.
减速器功能可处理三种情况: “ addData” , “ inputField”和“ addOneStudent”分别用于加载数据,受控表单和表单提交。
加载/渲染数据 (load/render data)
We used useEffect to trigger a dispatch action that loads the data into the App
component. This dispatch action is triggered when the page first mounts or after any subsequent page rendering. The reducer type “addData” paired with dispatch action is also shown below. We did not have to useEffect in this scenario, we could have just set the initialState.students
to local data. If we were to fetch data from an external API, it would be done with useEffect.
我们使用useEffect触发了将数据加载到App
组件中的调度动作。 在页面首次装入时或在任何后续页面呈现之后触发此分派操作。 减速器类型“ addData”与调度动作配对也显示在下面。 在这种情况下,我们不必使用Effect ,只需将initialState.students
设置为本地数据即可。 如果我们要从外部API获取数据,则可以使用useEffect来完成。
useEffect(() => {
dispatch({ type: "addData", data });
}, []);// reducer to handle "addData" action type
case "addData":
return { ...state, students: action.data };
with useState we would have done something like;
使用useState,我们会做类似的事情;
const [students, setStudents] = useState(data);
OR
const [students, setStudents] = useState([]);
useEffect(() => {
setStudents(data);
}, []);
控制形式 (controlled form)
We useReducer to handled controlled form and the corresponding operation within the reducer function is shown below
我们使用Reducer来处理受控表格,而reducer函数中的相应操作如下所示
const handleChange = (name, value) => {
dispatch({ type: "inputField", fieldname: name, value: value });
};// reducer to handle "inputField" action type
case "inputField":
return { ...state, [action.fieldname]: action.value };
with useState, we would have called the useState function twice and passed-in two separate callback functions to the form’s input onChange attribute.
使用useState ,我们将调用useState函数两次,并将两个单独的回调函数传递给表单的输入onChange属性。
const [name, setName] = useState("");
const [grade, setGrade] = useState("")const handleNameChange = (e) => {
setName(e.target.value);
};
const handleGradeChange = (e) => {
setGrade(e.target.value);
}
表格提交 (form submission)
The following dispatch action shown below is triggered when the form is submitted. The corresponding operation within the reducer function is shown below. A new student object is appended to the exciting students list without mutating state.
提交表单后,将触发以下所示的分派操作。 减速器功能内的相应操作如下所示。 一个新的学生对象将添加到令人兴奋的学生列表中,而不会改变状态。
const addStudents = (info) => {
dispatch({ type: "addOneStudent", info });
};// reducer to handle "addOneStudent" action type
case "addOneStudent":
let newId = state.students.length + 1;
let newStudent = {
grade: action.info.grade,
name: action.info.name,
id: newId,
};
return { ...state, students: [...state.students, newStudent] };
The useState version, shown below, would look similar to how we handled form submission with useReducer
如下所示, useState版本看起来类似于我们使用useReducer处理表单提交的方式
const [students, setStudents] = useState(data);
const addStudentFunction = (info) => {
let newId = students.length + 1;
let newStudent = { ...info, id: newId };
let newStudents = [...students, newStudent];
setStudents(newStudents);
};
Summary.
摘要。
we discussed when and how to replace useState with useReducer.
我们讨论了何时以及如何将useState替换为useReducer 。
we covered useReducer in react controlled forms.
我们以React受控形式介绍了useReducer 。
The github repository for the demo app is here
演示应用程序的github存储库在这里
翻译自: https://medium.com/@pojotorshemi/react-hooks-usereducer-7b9096f7a184