useReducer React 方法 [英] useReducer React approach

查看:37
本文介绍了useReducer React 方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 useReducer react 的 api,想知道理论(文档)部分和我实现的部分之间的区别.

I'm playing with useReducer react's api, and wonder to know the difference between the theoretical (documentation) part and one I implement.

带有 useReducer 钩子的组件的初始状态:

const [fields, dispatch] = React.useReducer(formReducer, {
        firstName: { value: '', isValid: false },
        lastName: { value: '', isValid: false },
    });

理论变量

 const formActionTypes = {
    firstName: 'FIRST_NAME',
    lastName: 'LAST_NAME',
};
....
function formReducer(state, action) {
   switch (action.type) {
    case formActionTypes.firstName:
        return { ...state, firstName: { ...action.payload } };
    case formActionTypes.lastName:
        return { ...state, lastName: { ...action.payload } };
    default:
        return state;
}
}
....
dispatch({
            type: formActionTypes[name], //name is input name
            payload: { value, isValid } //value is e.target.value
        });

我的实现

function formReducer(state, action) {
    return { ...state, [action.name]: { ...action.payload } };
}
 ....
    dispatch({
                name, //name is input name
                payload: { value, isValid } //value is e.target.value
            });

推荐答案

如果这就是您的要求,您展示的两个减速器都可以工作并产生相同的结果.我认为您从文档中获得的理论版本旨在展示一个特定的概念,但是您的减速器可能违反了该概念(尽管这没什么大不了;我们的工作是编写工作代码,而不是通过一些纯度测试!).

The two reducers you've shown will both work and produce identical results if that's what you're asking. I think the theoretical version version you're getting from the documentation is meant to demonstrate a particular concept, though, which your reducer arguably violates (though it's not a big deal; our job is to make working code, not to pass some purity test!).

具体来说,您通常希望将操作与状态分离.动作不应该只是状态数据结构的镜像;如果你想要这种耦合,你最好使用 useState 代替,直接设置状态.减速器旨在通过对动作的描述建模来将其解耦,然后只有减速器决定该动作如何作用于状态.例如,您可能决定添加一个清除表单按钮.使用您当前的模式,您必须分派两个动作,这将导致两个状态更新,因为您的动作密切建模状态.switch 语句模式允许您根据不同类型的操作轻松应用不同类型的逻辑.

Specifically, you typically want to somewhat decouple actions from state. The action shouldn't just be a mirror of your state data structure; if you want that coupling, you'd might as well use useState instead and just set the state directly. A reducer is meant to decouple this by you modeling a description of the action, and then it's only the reducer that decides how that action acts on state. You might, for example, decide to add a clear form button. With your current pattern, you'd have to dispatch two actions, which would cause two state updates, because your actions closely model the state. The switch statement pattern allows you to easily apply different types of logic based on different types of actions.

没有错误的答案,只是不同的方法各有千秋.这是我认为通过让 reducer 逻辑知道字段是否有效来引入更好的解耦的方法:

There are no wrong answers, just different approaches all with their merits. Here's one that I think introduces better decoupling by letting the reducer logic take care of knowing about whether a field is valid:

const SET_FIRST_NAME = Symbol();
const SET_LAST_NAME = Symbol();
const CLEAR_FORM = Symbol();

// Call action creators instead, like: dispatch(setFirstName(e.target.value));
const setFirstName = name => { type: SET_FIRST_NAME, value: name };
const setLastName = name => { type: SET_LAST_NAME, value: name };
const clearForm = () => { type: CLEAR_FORM };

const initialState = {
  firstName: { value: '', isValid: false },
  lastName: { value: '', isValid: false }
};

const notEmpty = value => !!(value && value.trim().length);

const validateFirstName = notEmpty; // Or replace with different logic
const validateLastName = notEmpty;

const reducer = (state, action) => {
  switch (action.type) {
    case SET_FIRST_NAME:
      return { 
        ...state, 
        firstName: {
          value: action.value, 
          isValid: validateFirstName(value) 
        } 
      }
    case SET_LAST_NAME:
      return { 
        ...state, 
        lastName: {
          value: action.value, 
          isValid: validateLastName(value) 
        } 
      }
    case CLEAR_FORM:
      return initialState;
    default:
      return state;
  }
};

这篇关于useReducer React 方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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