使用反应挂钩useState更新功能的正确方法是什么?

时间:2019-08-31 19:06:19

标签: reactjs react-hooks

考虑以下声明:

   const [stateObject, setObjectState] = useState({
      firstKey: '',
      secondKey: '',
    });

以下代码片段都正确吗?

A)

setObjectState((prevState) => ({
  ...prevState,
  secondKey: 'value',
}));

B)

setObjectState({
  ...stateObject,
  secondKey: 'value',
}));

我确定A)是正确的,但是有必要吗? B)似乎还可以,但是由于setObjectState是一个异步函数,因此stateObject可能没有最新值。

2 个答案:

答案 0 :(得分:0)

关于A的情况,我发现一个有用的事情是,您可以使用此方法从子组件更新状态,而只传递setObjectState的单个属性。例如,假设您的父组件的状态要从子组件更新。

父项:

import React, {useState} from 'react';
import ChildComponent from './ChildComponent';

export const ParentComponent = () => {
  const [parentState, setParentState] = useState({
    otherValue: null,
    pressed: false,
  });
  return (
    <ChildComponent setParentState={setParentState} />
  )
}

子组件:

import React from 'react';

export const ChildComponent = (props) => {
  const callback = () => {
    props.setParentState((prevState) => ({
      ...prevState
      pressed: true,
    }))
  }
  return (
    <button onClick={callback}>test button<button>
  )
}

按下按钮时,您应该希望看到状态已更新,同时还保留其初始值。至于两者之间的区别,两者都完成相同的事情。

答案 1 :(得分:0)

A将始终为您提供更新的值。 B 可能是正确的,但不一定。让我举个例子:

const Example = props => {
    const [counter, setCounter] = useState(0);

    useEffect(() => {
        // 0 + 1
        // In this first case the passed value would be the same as using the callback.
        // This is because in this cycle nothing has updated counter before this point.
        setCounter(counter + 1);

        // 1 + 1
        // Thanks to the callback we can get the current value
        // which after the previous iexample is 1.
        setCounter(latest_value => latest_value + 1);

        // 0 + 1
        // In this case the value will be undesired as it is using the initial
        // counter value which was 0.
        setCounter(counter + 1);
    }, []);

    return null;
};

当新值取决于更新后的值时,请使用回调,否则您可以简单地传递新值。

const Example = props => {
    const [hero, setHero] = useState('Spiderman');

    useEffect(() => {
        // Fine to set the value directly as
        // the new value does not depend on the previous one.
        setHero('Batman');

        // Using the callback here is not necessary.
        setHero(previous_hero => 'Superman');
    }, []);

    return null;
};

此外,在示例中,您给出使用两个不同的状态可能更好:

const [firstKey, setFirstKey] = useState("");
const [secondKey, setSecondKey] = useState("");