嘿,各位,我想知道是否有人能帮我理解useReducer。这是有人给我的建议,因为我使用的表单有很多输入,我想动态地使用这个应用程序的其他领域。我是新的反应,我正在努力使它的工作,我想。这是我目前正在做的工作。
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 ) } 我所遵循的指南似乎与其他指南的格式不同。由于我不太明白发生了什么,所以我无法将表单重置为默认值,这似乎是还原器的要点。教我试着作弊,抄别人的作业,我猜:)
发布于 2021-12-22 10:49:31
你的帖子清楚地反映了你对反应和钩子是如何工作的缺乏了解。请在阅读互联网上任何令人困惑的指南之前,先阅读正式文件。您不能在正式文档中出错,因为它首先演示了如何使用它。
首先,要使代码工作,就必须将useReducerState从组件中移出。为什么?每次呈现组件时,useReducerState都将是一个新函数。您的函数是一个钩子,最好将其移到它自己的文件中并导出它。
其次,如果您知道Redux,请将useReducer视为组件的本地存储区。useReducer的第一个参数是减速器,减速器是一个纯函数,将状态作为第一个参数传递,动作作为第二个参数,并返回一个新的状态。所以,我一点也不明白这句话:
const reducer = (prev, next) => ({ ...prev, ...next });“下一步”应该是一个动作,它是一个具有两个属性的对象:类型的(被分派的动作的类型)和的有效负载(好的,有效负载)。
这一行更令人困惑:
const [state, setState] = useReducerState({而useReducer的签名看起来是这样的:
const [state, dispatch] = useReducer(reducer, initialArg, init);所以你怎么会和setState在一起对我来说是个谜。
最后,我还没有在组件中看到任何调度(?)那么,为什么要使用useReducer呢?根据您的代码判断,您似乎希望使用一个useState,它确实返回数组中的setState。
由于我不太明白发生了什么,所以我无法将表单重置为默认值,这似乎是还原器的要点。
这里不清楚您的意思,但是还原器的目的是发送一个操作,它将决定您的状态中要更改什么,并返回新的状态。使用useReducer,您不必这样做:
setState(prevState => ({
...prevState,
[proPToUpdate]: value
}))正式文件的摘录:
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>
</>
);
}在你的例子中,类似于这样的东西:
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 });关于它的更多。是的,这个代码
const reducer = (prev, next) => ({ ...prev, ...next });
return useReducer(reducer, initialState);确实起作用了但你失去了可读性。让我们直言不讳吧。当使用减速器时,你必须将一个动作传递给它。一个动作必须有一个类型。上面的代码可以工作,但它是错误的。它正在转移useReducer的合法用途来获取,什么?更少的代码?是的,但绝不会以可读性和语义为代价。当您打算使用.map而不是.forEach时,这与使用.forEach是一样的。
如果我在某个地方看到这个(别人写的):
setState({ [proToUpdate]: value });你觉得我会怎么做?我会说,嘿,你的代码错了,应该是
setState(prevState => ({ ...prevState, [proToUpdate]: value }));然后把它修好。不知道有一个useReducer在幕后玩.这是错的。
我见过很多人做一些奇怪的事情来讨价还价几行代码,但这并不总是很漂亮,经常是来自于互联网上的指南,媒体上的等等!不要忘记,您可能不是一个人在处理这段代码。让它具有可读性,更重要的是,对每个人都有意义。
https://stackoverflow.com/questions/70443172
复制相似问题