React Reducer 真的应该是一个纯函数吗? [英] Should React Reducer really be a pure function?

查看:51
本文介绍了React Reducer 真的应该是一个纯函数吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

据说useReducer中使用的reducer函数是纯函数.如果我没记错的话,它的行为仅取决于它的输入参数——所以用相同的输入参数调用它两次具有相同的结果."(来自此处).还有(来自这里):

<块引用>

减速器应该:

  • 永远不要改变它的参数

  • 从不产生副作用(API 调用不会改变任何东西)

  • 永远不要调用非纯函数,即根据输入以外的因素(例如 Date.now() 或 Math.random())改变其输出的函数

关于这个我有两个问题:

  1. 谁能解释为什么reducer必须是纯函数?例如如果在接收相同输入时返回两个不同的输出,会出现什么问题?或者,如果它有副作用会怎样?
  2. 考虑以下示例代码:

 导出函数 MyComponent(props: IPropTypes) {const reducer = (prevState, action) =>{newState = deepClone(prevState);newState.count = newState.count + props.count;返回新状态;}const [状态,调度] = useReducer(reducer, ....);返回 (<div>...</div>)}

我是否正确地认为上述 reducer 不是一个好的 reducer,因为它也依赖于 props(这不是它的输入)?为什么这是一件坏事?

解决方案

参考官方Redux 文档,使用纯函数编写 reducer 会增加您重用 reducer 的机会.

我认为您可以通过将 props.count 作为函数的参数,将它放在 action 对象中来使您的 reducer 变得纯粹.我更喜欢制作 payload 字段.

这是我写的工作代码:代码和盒子,这就是我改变你的组件的方式:

const reducer = (state, action) =>{开关(动作.类型){案例增量":返回 {...状态,计数:state.count + action.payload};默认:返回状态;}};导出默认值(道具)=>{const [state, dispatch] = useReducer(reducer, { count: 0 });const 增量 = () =>dispatch({ type: "INCREMENT", payload: props.count });返回 (<div><p>当前:{state.count}</p><button onClick={increment}>Increment</button>

);}

It is said that the reducer function used in useReducer is a pure function. If I'm not wrong, "Its behaviour depends only on its input parameters -- so calling it twice with the same input parameters has the same resulting effect." (from here). And also (from here):

A reducer should:

  • never mutate its arguments

  • never generate side-effects (no API calls changing anything)

  • never call non-pure functions, functions that change their output based on factors other than their input (e.g. Date.now() or Math.random())

I have two questions regarding this:

  1. Can any one explain why the reducer must be a pure function? e.g. what can go wrong if it returns two different outputs while receiving the same input? Or, what happens if it has side-effects?
  2. Consider the following sample code:

    export function MyComponent(props: IPropTypes) {
        const reducer = (prevState, action) => {
            newState = deepClone(prevState);
            newState.count = newState.count + props.count;
            return newState;
        }
        
        const [state, dispatch] = useReducer(reducer, ....);
        
        return (<div>
             ...
             </div>)
    }

Am I right that the above reducer is not a good reducer because it is also dependent on props (which is not its input)? Why is this a bad thing?

解决方案

Referring the official Redux documentation, writing reducers with pure functions increases the chance you reuse your reducers.

I think you can make your reducer pure, just by giving the props.count as an argument of a function, by putting it inside the action object. I prefer making a payload field.

Here is a working code I wrote: codesandbox, and this is how I changed your Component:

const reducer = (state, action) => {
  switch(action.type){
    case "INCREMENT":
      return {
        ...state,
        count: state.count + action.payload
      };
    default:
      return state;
  }
};

export default (props) => {
  const [state, dispatch] = useReducer(reducer, { count: 0 });
  const increment = () => dispatch({ type: "INCREMENT", payload: props.count });

  return (
    <div>
      <p>Current: {state.count}</p>
      <button onClick={increment}>Increment</button>
    </div>
  );
}

这篇关于React Reducer 真的应该是一个纯函数吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆