Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/431.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 用户教育者反应法_Javascript_Reactjs_React Hooks - Fatal编程技术网

Javascript 用户教育者反应法

Javascript 用户教育者反应法,javascript,reactjs,react-hooks,Javascript,Reactjs,React Hooks,我正在玩useReducerreact的api,想知道理论(文档)部分和我实现的部分之间的区别 与useReducer挂钩的组件的初始状态: const [fields, dispatch] = React.useReducer(formReducer, { firstName: { value: '', isValid: false }, lastName: { value: '', isValid: false }, }); 理论变量 const

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

与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
            });

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

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

没有错误的答案,只有不同的方法,都有各自的优点。这里有一个我认为可以通过让reducer逻辑了解字段是否有效来引入更好的解耦:

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和action确保只有action负责此流。