[英]React - UseState - How to partially update state object
Hi,你好,
I'm trying to partially update my state object :我正在尝试部分更新我的状态对象:
const [elephantProp, setElephantProp] = useState({
name: "",
color: "",
size: "",
race: "",
country: "",
});
Let's say I want to update only color and size parameters.假设我只想更新颜色和大小参数。
Dynamically change parameters (according to the input object) :动态改变参数(根据输入对象):
const handleChange = (input) => {
Object.keys(input).forEach((key) => {
setElephantProp({ ...elephantProp, [key]: input[key] });
};
Output : change only last parameter (size).输出:仅更改最后一个参数(大小)。
Set all parameters at once :一次设置所有参数:
const handleChange = (input) => {
setElephantProp({ ...elephantProp, color: input.color, size: input.size });
};
Output : Works but is not dynamic (if I add a parameter to the input object there will be no effects)输出:有效但不是动态的(如果我向输入对象添加参数,则不会有任何影响)
Do you have any ideas on how to dynamically update some of my state variables ?你对如何动态更新我的一些状态变量有什么想法吗?
Maybe I should consider splitting into multiple state variables (not convenient with a lot of variables) or using nested objects ?也许我应该考虑拆分成多个状态变量(很多变量不方便)或使用嵌套对象?
From you code I am going to assume that input
is an object representing the state updates, eg根据您的代码,我将假设
input
是一个表示状态更新的对象,例如
{
name: "Dumbo",
country: "USA"
}
In this case you can simply do:在这种情况下,您可以简单地执行以下操作:
const handleChange = (input) => {
setElephantProp({ ...elephantProp, ...input });
}
As ...input
come last, its properties will overwrite elephantProp
properties that have the same key.当
...input
最后出现时,它的属性将覆盖具有相同键的elephantProp
属性。 Please notice in this way all input
keys which are not present in elephantProp
, will be added to the state;请注意,以这种方式,所有在
elephantProp
中不存在的input
键都将被添加到状态中; eg例如
const elephantProp = { name: "", color: "", size: "", race: "", country: "", }; const input = { name: "Dumbo", country: "USA", ableToFly: true, }; const updatedElephantProp = { ...elephantProp, ...input } // => the updated state will contain the key/value pair 'ableToFly: true' too console.log(updatedElephantProp)
This behaviour might be desirable or not, depending on your needs and project specifications.根据您的需要和项目规范,这种行为可能是可取的,也可能是不可取的。
You can use concept useReducer
- is usually preferable to useState when you have complex state logic that involves multiple sub-values - useReducer您可以使用概念
useReducer
- 当您具有涉及多个子值的复杂状态逻辑时,通常比 useState 更可取 - useReducer
const [changes, onChange] = useReducer((value, change) => ({...(value || {}), ...change}), {});
//used
const {name, color, size, race, country} = changes;
const handleChange = change => {
//example change = {name: 'alex'}
onChange(change);
};
React recommends using multiple states for the different variables. React 建议为不同的变量使用多个状态。 However, if you did want to set a full object, you'd likely rather copy the object, and
setState
only once.但是,如果您确实想设置一个完整的对象,您可能宁愿复制该对象,并且只复制一次
setState
。 You loop might not be caught properly by the rerendering, as it is an async function.您的循环可能不会被重新渲染正确捕获,因为它是一个异步函数。
I'm not sure what your implementation is, but something like this should work:我不确定你的实现是什么,但这样的事情应该有效:
const handleChange = (objectIn) => {
// create a new object merging the old one and your input
const newElephant = {
...elephantProps,
...objectIn
}
setElephantProps(newElephant)
}
This should handle your case gracefully.这应该可以优雅地处理您的情况。 If you're using multiple inputs, I usually handle it that way:
如果您使用多个输入,我通常会这样处理:
const onChange = ({ target: { value, name } }) => setElephant({
...elephant,
[name]: value
})
return <input onChange={onChange} name="size" value={elephant.size} />
You can pass 2-nd param to handleChange, for example:您可以将第二个参数传递给 handleChange,例如:
const handleChange = (input, name) => {
setElephantProp({ ...elephantProp, [name]: input[name] });
};
One of your solutions here: codesandbox.io or bellow code using this approach.您的解决方案之一:codeandbox.io或使用此方法的波纹管代码。
const onChangeHandaller = (e) => {
setElephantProp({ ...elephantProp, [e.target.name]: e.target.value });
};
const [elephantProp, setElephantProp] = useState({
name: "",
color: "",
size: "",
race: "",
country: ""
});
const onChangeHandaller = (e) => {
setElephantProp({ ...elephantProp, [e.target.name]: e.target.value });
};
return (
<div className="App">
Name:{" "}
<input
value={elephantProp.name}
name="name"
onChange={(e) => onChangeHandaller(e)}
/>{" "}
<br />
Color:{" "}
<input
value={elephantProp.color}
name="color"
onChange={(e) => onChangeHandaller(e)}
/>{" "}
<br />
Size:{" "}
<input
value={elephantProp.size}
name="size"
onChange={(e) => onChangeHandaller(e)}
/>{" "}
<br />
Race:{" "}
<input
value={elephantProp.race}
name="race"
onChange={(e) => onChangeHandaller(e)}
/>{" "}
<br />
Country:{" "}
<input
value={elephantProp.country}
name="country"
onChange={(e) => onChangeHandaller(e)}
/>{" "}
<br />
</div>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.