什么是reducer

2020年7月2日 ... ☕️ 2 min read

reducer的概念之前就有,不过近年来随着redux的使用为我们所熟知。那么reducer是什么呢?

通常情况下,reducer会接受两个参数:当前状态(累加值)和一个action(当前值),然后返回一个新的状态。

(state, action) => newState

基本上,我在三个地方使用reducer(或其概念):数组、react的useReducer和redux的reducer。

数组方法Array.prototype.reduce

reduce会在数组的每个元素上依次调用回调方法,并最终返回一个值。用法为

const arr = [1, 2, 3, 4];
const reducer = (accumulator, currentValue) => accumulator + currentValue;
arr.reduce(reducer); // output 10

可以看到,reduce接受一个函数作为reducer,这个函数就是reduce方法的关键。

reducer接受4个参数:累加器、当前值、当前下标、原始数组。

reducer(accumulator, currentValue[, index[, array]] )

必要的两个参数是:累加器(state)和当前值(action)。

开始在元素上依次执行reducer:

当前下标 累加器(state) 当前值(action) result
0 0 1 1
1 1 2 3
2 3 3 6
3 6 4 10

可以看出,state每次都是不一样的(可以想到,内部有个循环,核心功能是当次函数的输出,作为下次函数的输入)。

用map模拟一下,流程差不多是这样(忽略state和action意外的参数):

Array.prototype._reduce = function (fn) {
  let res = 0;
  this.map((item, index) => {
    res = fn(res, item);
  });
  return res;
}

const arr = [1, 2, 3, 4];
const reducer = (accumulator, currentValue) => accumulator + currentValue;
arr._reduce(reducer); // output 10

react中的useReducer

一样的思路。

const [state, dispatch] = useReducer(reducer, initialArg, init);

useReducer接受一个reducer和初始化函数,返回当前的state和分发函数(dispatch)。这里的state只能通过dispatch来更改,没有具体的setXxx函数。

reducer是核心函数,接受两个参数:state和action。

摘取官方范例:

const initialState = {count: 0};

function reducer(state, action) {
  switch (action.type) {
    case 'increment':
      return {count: state.count + 1};
    case 'decrement':
      return {count: state.count - 1};
    default:
      throw new Error();
  }
}

function Counter() {
  const [state, dispatch] = useReducer(reducer, initialState);  return (
    <>
      Count: {state.count}
      <button onClick={() => dispatch({type: 'decrement'})}>-</button>
      <button onClick={() => dispatch({type: 'increment'})}>+</button>
    </>
  );
}

state存储在hooks的内部来控制。相当于批量处理了useState,并伸出统一的dispatch方法,通过该方法实际操作state。

注意,dispatch除了type,还可以携带其他参数(如累加具体数值),扩展性更强。

如果把这个结构放在app的最外层,将state作为context传入整个app,那么就是一个简单的redux替代品,如。

redux的reducer

-> 文档在此

#react#what-is

SideEffect is a blog for front-end web development.
Code by Axiu / rss