useReducer是基于redux的思想,同时也是useState的替代方案。
原生useReducer的特点
- 接收两个参数,第一个参数是reducer函数,第二个参数是一个初始的状态值。
- useReducer返回的是一个数组,数组的第一个元素是存储的状态,第二个元素是触发action的方法。
更多更详细的关于useReducer的用法,请看我的这篇博客需要掌握的Hooks之useReducer与useContext
手写useReducer
实现useReducer需要注意的几点:
- reducer函数和初始的状态值是用户自定义的。
- reducer函数接受两个参数分别是state和action。
- useReducer函数接收用户自定以得reducer函数和初始的状态值。
- 在useReducer函数中调用到了useState这个钩子函数。
第一步:使用useState获取到用户传递的初始状态值
const [state,setState] = useState(initialState);
第二步:通过setState执行用户dispatch过来的action
let dispatch = (action) => {
setState(reducer(state,action))
}
第三步:返回一个数组数组的第一个参数是状态值,第二个状态值是设置这个状态的方法
return [state,dispatch]
完整实现
import React,{useState} from 'react'
import ReactDOM from 'react-dom'
/**
* @description: 手写useReducer
* @param {*}
* @return {*}
*/
function useReducer(reducer,initialState) {
const [state,setState] = useState(initialState);
let dispatch = (action) => {
setState(reducer(state,action))
}
return [state,dispatch]
}
function App() {
const reducer = (state,action) => {
switch (action.type) {
case 'increment':
return state + 1;
case 'decrement':
return state - 1;
default:
return state;
}
}
const [count,dispatch] = useReducer(reducer,0)
return (
<>
<h1>当前求和为:{count}</h1>
<button onClick={() => dispatch({type: 'increment'})}>点我+1</button>
<button onClick={() => dispatch({type: 'decrement'})}>点我-1</button>
</>
)
}
ReactDOM.render(<App />, document.querySelector('#root'));
在线实现
值得深思的问题
-
通过实现useReducer我们可以看出这和redux中的reducer的实现思想是一样的,编程思想有时候即使在不同的应用场景中却有着共同的实现思想。
-
准确理解useReducer的关键是理解useReducer中state的流动过程。