React-UseState-如何部分更新状态对象

时间:2020-09-14 10:17:27

标签: javascript reactjs react-hooks state

问题

嗨,

我正在尝试部分更新我的状态对象:

const [elephantProp, setElephantProp] = useState({
        name: "",
        color: "",
        size: "",
        race: "",
        country: "",
    });

比方说,我只想更新颜色和尺寸参数。

我尝试过的

1

动态更改参数(根据输入对象):

const handleChange = (input) => {
    Object.keys(input).forEach((key) => {
        setElephantProp({ ...elephantProp, [key]: input[key] });
    };

输出:仅更改最后一个参数(大小)。

2

一次设置所有参数:

const handleChange = (input) => {
        setElephantProp({ ...elephantProp, color: input.color, size: input.size });
    };

输出:有效,但不是动态的(如果我向输入对象添加参数,将不会有效果)

您对如何动态更新某些状态变量有任何想法吗?

也许我应该考虑拆分为多个状态变量(使用许多变量不方便)还是使用嵌套对象?

5 个答案:

答案 0 :(得分:1)

根据您的代码,我将假设input是代表状态更新的对象,例如

{
    name: "Dumbo",
    country: "USA"
}

在这种情况下,您可以简单地执行以下操作:

const handleChange = (input) => {
    setElephantProp({ ...elephantProp, ...input });
}

最后...input的属性将覆盖具有相同键的elephantProp属性。 请注意,以这种方式将input中不存在的所有elephantProp键添加到状态中;例如

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)

取决于您的需求和项目规范,此行为是否可取。

答案 1 :(得分:0)

您可以使用概念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);
    };

答案 2 :(得分:0)

React建议对不同的变量使用多个状态。 但是,如果您确实想设置一个完整的对象,则可能宁愿复制该对象,并且setState仅复制一次。重新循环可能无法正确捕获循环,因为它是异步功能。

我不确定您的实现是什么,但是这样的方法应该可以工作:

const handleChange = (objectIn) => {
  // create a new object merging the old one and your input
  const newElephant = {
    ...elephantProps,
    ...objectIn
  }
  setElephantProps(newElephant)
}

这应该可以很好地处理您的情况。如果您使用多个输入,我通常会这样处理:

  const onChange = ({ target: { value, name } }) => setElephant({
    ...elephant,
    [name]: value
  })
  return <input onChange={onChange} name="size" value={elephant.size} />

答案 3 :(得分:0)

您可以将第二个参数传递给handleChange,例如:

const handleChange = (input, name) => {
    setElephantProp({ ...elephantProp, [name]: input[name] });
};

答案 4 :(得分:0)

您的一种解决方案here: codesandbox.io或使用这种方法的下面的代码。

  const onChangeHandaller = (e) => {
    setElephantProp({ ...elephantProp, [e.target.name]: e.target.value });
  };

enter image description here

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>