useState 中的初始值在重新渲染后未更新

Initial values in useState not updated after re-render

很确定我遗漏了一些关于 React 的基础知识。

代码如下:

export function EditTagsModal({existingTags}) {
  console.log('existingTags', existingTags);

  const [selectedTags, setSelectedTags] = React.useState(existingTags);

  console.log('selectedTags:', selectedTags);
  ...
}

在父组件中,<EditTagsModal />是这样消耗的:

{tags && <EditTagsModal existingTags={tags} /> }

这是怎么回事:

  1. existingTags['hello']
  2. 开头
  3. setSelectedTags 正在做它的事情。
  4. selectedTags 现在是 ['hello', 'world', 'world']
  5. 然后我将标签发送到服务器,关闭模态,父级重新渲染。
  6. 现在服务器返回的 tags['hello', 'world'],没有重复。
  7. 事情是这样的:现在我再次打开模式,我仍然在 selectedTags 中看到我的值(在上面的那一秒 console.log 中)有重复项,而不是 tags(第一个console.log)来自我的服务器。

React 怎么了?

useState 钩子中的 selectedTags 状态只初始化一次。

如果 tags 仍然是真实定义的数组(即使空数组也是真实的和定义的),那么 EditTagsModal 组件仍然由 [=15= 安装].如果 tags 值,因此 existingTags 属性更新并且 EditTagsModal 被重新渲染,那么你应该实现一个 useEffect 钩子,依赖于 existingTags 属性在 prop 值更新时更新本地状态。

useEffect(() => {
  setSelectedTags(existingTags);
}, [existingTags]);

useEffect 与依赖项数组是 class 组件的 componentDidMount 的同义词componentDidUpdate 生命周期方法。

正如评论中提到的那样,useState(existingTags)(或任何你称之为的东西)只会在第一次渲染时使用 existingTags。

During the initial render, the returned state (state) is the same as the value passed as the first argument (initialState).

在此之后,在重新渲染时,useState 函数不会根据传入的 props 的新更改来更改状态。

export function EditTagsModal(props) {
  console.log('existingTags', existingTags);
  
  const { existingTags } = props;
  const [selectedTags, setSelectedTags] = React.useState(existingTags);
  useEffect(() => { setSelectedTags](existingTags)}, [existingTags] )


  console.log('selectedTags:', selectedTags);
  ...
}