首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >困惑于UseReducer

困惑于UseReducer
EN

Stack Overflow用户
提问于 2021-12-22 00:53:48
回答 1查看 114关注 0票数 0

嘿,各位,我想知道是否有人能帮我理解useReducer。这是有人给我的建议,因为我使用的表单有很多输入,我想动态地使用这个应用程序的其他领域。我是新的反应,我正在努力使它的工作,我想。这是我目前正在做的工作。

代码语言:javascript
复制
    const Form= () => {
const useReducerState = (initialState = {
    
}) => {    
    const reducer = (prev, next) => ({ ...prev, ...next });
    return useReducer(reducer, initialState);
};

const [state, setState] = useReducerState({
input1: "",
input2: "",
input 3: "",
input 4: "",
input 6: "",
input 7: "",
input 8: "",
input 9: "",
 });


 const handleChange = (e) => {        
    let proToUpdate = e.target.name;
    let value = e.target.value;
    setState({ [proToUpdate]: value });    
     }

const {
    input 1,
    input 2,
    input 3,
    input 4,
    input 5, 
    input 6,
    input 7,
    input 8,
    input 9
    
} = state;



return ( jsx form with inputs matching the state above ) } 

我所遵循的指南似乎与其他指南的格式不同。由于我不太明白发生了什么,所以我无法将表单重置为默认值,这似乎是还原器的要点。教我试着作弊,抄别人的作业,我猜:)

EN

回答 1

Stack Overflow用户

发布于 2021-12-22 10:49:31

你的帖子清楚地反映了你对反应和钩子是如何工作的缺乏了解。请在阅读互联网上任何令人困惑的指南之前,先阅读正式文件。您不能在正式文档中出错,因为它首先演示了如何使用它。

首先,要使代码工作,就必须将useReducerState从组件中移出。为什么?每次呈现组件时,useReducerState都将是一个新函数。您的函数是一个钩子,最好将其移到它自己的文件中并导出它。

其次,如果您知道Redux,请将useReducer视为组件的本地存储区。useReducer的第一个参数是减速器,减速器是一个纯函数,将状态作为第一个参数传递,动作作为第二个参数,并返回一个新的状态。所以,我一点也不明白这句话:

代码语言:javascript
复制
const reducer = (prev, next) => ({ ...prev, ...next });

“下一步”应该是一个动作,它是一个具有两个属性的对象:类型的(被分派的动作的类型)和的有效负载(好的,有效负载)。

这一行更令人困惑:

代码语言:javascript
复制
const [state, setState] = useReducerState({

useReducer的签名看起来是这样的:

代码语言:javascript
复制
const [state, dispatch] = useReducer(reducer, initialArg, init);

所以你怎么会和setState在一起对我来说是个谜。

最后,我还没有在组件中看到任何调度(?)那么,为什么要使用useReducer呢?根据您的代码判断,您似乎希望使用一个useState,它确实返回数组中的setState。

由于我不太明白发生了什么,所以我无法将表单重置为默认值,这似乎是还原器的要点。

这里不清楚您的意思,但是还原器的目的是发送一个操作,它将决定您的状态中要更改什么,并返回新的状态。使用useReducer,您不必这样做:

代码语言:javascript
复制
setState(prevState => ({
  ...prevState,
  [proPToUpdate]: value
}))

正式文件的摘录:

代码语言:javascript
复制
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>
    </>
  );
}

在你的例子中,类似于这样的东西:

代码语言:javascript
复制
const initialState = {
input1: "",
input2: "",
input 3: "",
input 4: "",
input 6: "",
input 7: "",
input 8: "",
input 9: "",
 }

function reducer(state, action) {
  switch (action.type) {
    case 'setInput1':
      return { ...state, input1: action.payload};
    case 'setInput2':
      return { ...state, input2: action.payload};
    case 'reset':
      return initialState;
    default:
      throw new Error();
  }
}


...
const [state, dispatch] = useReducer(reducer, initialState)
...
dispatch({ type: 'reset' });
dispatch({ type: 'setInput1', payload: value });

关于它的更多。是的,这个代码

代码语言:javascript
复制
const reducer = (prev, next) => ({ ...prev, ...next });
return useReducer(reducer, initialState);

确实起作用了但你失去了可读性。让我们直言不讳吧。当使用减速器时,你必须将一个动作传递给它。一个动作必须有一个类型。上面的代码可以工作,但它是错误的。它正在转移useReducer的合法用途来获取,什么?更少的代码?是的,但绝不会以可读性和语义为代价。当您打算使用.map而不是.forEach时,这与使用.forEach是一样的。

如果我在某个地方看到这个(别人写的):

代码语言:javascript
复制
setState({ [proToUpdate]: value });

你觉得我会怎么做?我会说,嘿,你的代码错了,应该是

代码语言:javascript
复制
setState(prevState => ({ ...prevState, [proToUpdate]: value }));

然后把它修好。不知道有一个useReducer在幕后玩.这是错的。

我见过很多人做一些奇怪的事情来讨价还价几行代码,但这并不总是很漂亮,经常是来自于互联网上的指南,媒体上的等等!不要忘记,您可能不是一个人在处理这段代码。让它具有可读性,更重要的是,对每个人都有意义。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70443172

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档