useReducer是useState的复杂版,使用示例:
const intialState={
n:0
}
const reducer=(state,action)=>{
if(action.type==='add'){
return {n:state.n+action.number}
}else if(action.type==='multi'){
return {n:state.n*2}
}else{
throw new Error('unknown')
}
}
function App(){
const [state,dispatch]=useReducer(reducer,intialState)
const onClick=()=>{
dispatch({type:'add',number:1})
}
const onClick2=()=>{
dispatch({type:'add',number:2})
}
return (
<div>
n:{state.n}
<button onClick={onClick}>+1</button>
<button onClick={onClick2}>+2</button>
</div>
)
}
使用步骤:
- 创建初始值
intialState - 创建对state的所有操作的函数
reducer(state,action)第一个参数state是现在的state,第二个参数action是一个对象,表示对数据进行的操作。通过判断action.type,返回不同的新state。这个action也可以有其他属性 - 调用
userReducer(reducer,intialState),得到一个读数据API:state和一个写API:dispatch - 在事件处理函数中,调用dispatch对数据修改。
dispatch({type:'add',number:1})dispatch传一个对象,就是action
什么时候可以用useReducer呢?如果使用useState时,要把多个变量组合在一起,也就是都放到一个对象里进行统一操作时,就可以改用useReducer
一个使用useReducer的表单例子:
const initFormData = { // 1. 创建初始化数据
name: "",
age: 18,
nationality: "汉族"
};
function reducer(state, action) { // 2. 创建reducer函数,汇聚了所有操作
switch (action.type) {
case "patch": // 更新数据
return { ...state, ...action.formData };
case "reset": // 重置
return initFormData;
default:
throw new Error();
}
}
function App() {
const [formData, dispatch] = useReducer(reducer, initFormData); // 3.
const onSubmit = () => {};
const onReset = () => {
dispatch({ type: "reset" });
};
return (
<form onSubmit={onSubmit} onReset={onReset}>
<div>
<label>
姓名
<input value={formData.name}
onChange={e =>
dispatch({ type: "patch", formData: { name: e.target.value } })
} // 4. 当用户往输入框里输入时,触发onChange事件,调用dispatch
/> //修改formData的name
</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>
);
}
由于每个input的value属性都读了formData里的对应属性,所以在输入框里输入,会在下边的展示区即时展示输入的新内容。
