【问题标题】:React clearing all keys rather than shallow merging single key反应清除所有键而不是浅合并单个键
【发布时间】:2021-06-02 19:40:41
【问题描述】:

我从 API 中提取数据,然后允许用户在 react 中修改该数据,之后我会将更新后的状态发送到服务器。

我的 API 提供以下 JSON:

{
    "id": 1,
    "title": "Test Campaign",
    "impressions": 12,
}

我的组件看起来像这样:

function Campaign() {

  const [data, setData] = useState([])

  useEffect(async () => {
    const result = await axios('/campaigns/1')
    setData(result.data);
  }, []);

  const handleChange = (event) => {
    setData({[event.target.name]: event.target.value});
  }

  return (
    <div className='row'>
      <div className='col-12'>
        <h2>{ data.title }</h2>
        <input
          type='number'
          value={data.impressions}
          name='impressions'
          onChange={e => handleChange(e)}
        />
      </div>
    </div>
  )
}

但是,运行此代码会导致所有处于data 状态的键被覆盖(因此我的h2 标记不显示任何内容)。我的理解是 React State 进行了浅合并,所以在这种情况下只会更新 impressions key:value?

【问题讨论】:

    标签: javascript reactjs use-state


    【解决方案1】:

    函数式组件的 useState 钩子实际上并不进行浅层合并状态更新,因此您需要自己管理。

    使用functional state update 访问前一个状态以浅拷贝到下一个状态。

    注意

    与类组件中的setState 方法不同,useState 不会自动合并更新对象。你可以复制这个 通过将函数更新器形式与对象传播相结合的行为 语法:

    setState(prevState => {
      // Object.assign would also work
      return {...prevState, ...updatedValues};
    });
    

    您可能还想确保保持状态不变。由于您正在通过键值对更新您的状态,我假设您实际上使用了一个对象。

    const [data, setData] = useState({}); // <-- empty object initial state
    
    const handleChange = (event) => {
      setData(data => ({
        ...data, // <-- shallow copy existing state
        [event.target.name]: event.target.value,
      }));
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-12-15
      • 2015-03-12
      • 2014-07-30
      • 2021-01-28
      • 2012-07-05
      相关资源
      最近更新 更多