这是我参与11月更文挑战的第9天,活动详情查看:2021最后一次更文挑战
在上一篇文章里我们学了useEffect,我们可以利用useEffect在组件渲染时触发副作用(还能够限制副作用的触发条件),还能够用多个useEffect将副作用关注点分离,避免把多个副作用堆在一个组件的生命周期里。今天我们一起来学习一下另外一个React Hooks——useReducer
一、Reducer复习
在之前的文章里,我们有接触过Reducer,它是Redux里的一个重要部分,在Redux里我们主要这么使用Reducer:
- 创建
Reducer函数,入参为初始State与Action,内部通过Action.type定义不同逻辑,最终返回新的State - 利用
Reducer作为参数进行React.createStore,得到Store实例 - 在使用
Store的组件中导入Store实例对象 - 使用时,调用
Store.dispatch( { type:"example" } )进行派发事件即可
//Store.js
const Reducer = ({ content:"初始State" },action)=>{
switch(action.type){
case "A" : return { content:"A" }
case "B" : return { content:"B" }
default : return { content:"C" }
}
}
const Store = React.createStore(Reducer);
export default Store;
//A.js
import Store from "./Redux/Store.js"
class A extends React.Component {
render() {
return (
<div onClick={ ()=>{ Store.dispatch( {type:"A"} ) } }>Click Me</div>
)
}
}
二、useReducer学习
useReducer的使用:
传入参数:
- 参数一:
Reducer函数 - 参数二:
Action返回内容: - 返回一个数组
- 数组第一项:当前
State - 数组第二项:用于派发的函数,传入
Action,相当于Redux中的Store.dispatch( {type:"example"} )使用场景: State逻辑复杂且有多个子值- 下一个
State需要依赖上一个State来处理获得
使用流程:
- 创建
Reducer函数,按照上文编写Reducer逻辑(Reducer函数中的State参数可以在内部逻辑中作为上一个State参与逻辑处理) - 新建一个
State对象作为初始State - 将
Reducer函数与State对象作为参数传入useReducer,并通过解构来接收useReducer钩子返回的State与用于派发更新的setReducer函数 - 如果需要进行派发,则调用:
setReducer( {type:"example"} )来进行Action派发,State会进行更新
//初始化State
const initialState = { content:"init" }
//定义Reducer
const Reducer = (state,action) => {
switch(action.type){
case "A" : return { content:"A" }
case "B" : return { content:"B" }
default : return { content:"C" }
}
}
function showExampleA() {
//使用useReducer并接收State与setReducer
let [state, setReducer] = useReducer(Reducer,initialState)
//State的使用与Action派发
return (
<div>
<h1>{state.content}</h1>
<button onClick={ ()=>{ setReducer( {type:"A"} ) } }>Click Me</button>
</div>
)
}
另外,上文还有提到我们可以通过上一个State来进行下一个State处理的逻辑,我们一起来看一下:
//初始化State
const initialState = { count:0 }
//定义Reducer
const Reducer = (state,action) => {
switch(action.type){
case "one" : return { content:state.count+1 }
case "two" : return { content:state.count+2 }
default : return { content:state.count+3 }
}
}
function showExampleA() {
//使用useReducer并接收State与setReducer
let [state, setReducer] = useReducer(Reducer,initialState)
//State的使用与Action派发
return (
<div>
<h1>{state.count}</h1>
<button onClick={ ()=>{ setReducer( {type:"one"} ) } }>Click Me To Add 1</button>
<button onClick={ ()=>{ setReducer( {type:"two"} ) } }>Click Me To Add 2</button>
<button onClick={ ()=>{ setReducer( {type:""} ) } }>Click Me To Add 3</button>
</div>
)
}