useReducer
首先创建一个button和n的state
import React,{useState} from "react";
import "./styles.css";
export default function App() {
const [n,setN] = useState(0)
const onClick =()=>{
setN(x=>x+1)
}
return (
<div className="App">
<h1>n: {n}</h1>
<button onClick={onClick}>+1</button>
</div>
);
}

1. 创建初始值initalState
const initial ={
n:0
}
2. 创建所有操作reducer(state,action)
const reducer = (state,action) => {
if(action.type === 'add') {
return {n:state.n+1}
} else if(action.type==='mult') {
return {n:state.n*2}
} else {
throw new Error('error')
}
}
创建一个带有+1 和 *2 功能的reducer
3.将创建的reduder传给userReducer得到读写方法
useReducer接受两个参数,一个是reducer,另一个是initial,
const [state,dispatch] = useReducer(reducer,initial)
const {n} = state
返回两个参数,一个是state保存值,另一个是dispatch

取出state中的n后,我们发现它就是initial中的n.和我们一开始使用的useState的值相同
4. dispatch({type:'操作方法'})
我们修改一下之前的onClick方法,调用dispatch
const onClick =()=>{
dispatch({type:'add'})
}

此时能够看到,点击后触发了+1的操作,达到了之前useState的setN的效果
我们可以将加的参数传给onClick,然后在reducer中增加传入的参数
const reducer = (state,action) => {
if(action.type === 'add') {
return {n:state.n+action.number}
} else if(action.type==='mult') {
return {n:state.n*2}
} else {
throw new Error('error')
}
}
const onClickAdd =(number)=>{
dispatch({type:'add',number})
}
我们再创一个按钮,用来做乘的操作
<button onClick={()=>onClickMult(2)}>mult * 2 </button>
修改一下reducer和onClick
const onClickMult = (number)=>{
dispatch({type:'mult',number})
}
const reducer = (state,action) => {
if(action.type === 'add') {
return {n:state.n+action.number}
} else if(action.type==='mult') {
return {n:state.n*action.number}
} else {
throw new Error('error')
}
}
先+1,在乘2

此时我们的click方法非常的简单,因为操作被我们聚拢在reducer中,我们在click中只触发dispatch,然后调用相对应的reducer
通常情况下,useReducer适合用来处理表单

<form onSubmit={onSubmit} onReset={onReset}>
<div>
<label>
姓名
<input
value={formData.name}
onChange={e =>
dispatch({ type: "patch", formData: { name: e.target.value } })
}
/>
</label>
</div>
<div>
<label>
年龄
<input
value={formData.age}
onChange={e =>
dispatch({ type: "patch", formData: { age: e.target.value } })
}
/>
</label>
</div>
<div>
<label>
民族
<input
value={formData.nationality}
onChange={e =>
dispatch({
type: "patch",
formData: { nationality: e.target.value }
})
}
/>
</label>
</div>
<div>
<button type="submit">提交</button>
<button type="reset">重置</button>
</div>
<hr />
{JSON.stringify(formData)}
</form>
我们可以将reducer分为2个操作,patch(更新任意一项表单),reset(重置所有表单)
const initFormData = {
name: "",
age: 18,
nationality: "汉族"
};
function reducer(state, action) {
switch (action.type) {
case "patch":
return { ...state, ...action.formData };
case "reset":
return initFormData;
default:
throw new Error();
}
}

我们修改姓名,此时触发patch操作
网友评论