javascript - Hook 状态落后于 prop 状态

标签 javascript reactjs react-hooks

我对 Prop 如何与钩子(Hook)创建的状态进行交互有疑问。

在下面的示例中,钩子(Hook)中保存的状态始终落后于属性中定义的状态。

认为我明白为什么会发生这种情况。生命周期似乎是这样的:

  1. 组件渲染
  2. handleClick 定义为可以访问基于此渲染的范围
  3. 按钮被点击并调用handleClick
  4. handleClick 仍然只能访问渲染中定义的范围,因此,items 仍然为空
  5. add 被调用;父组件中的状态已更新,但 setHookItems 将使用定义 handleClick 时在 props 中定义的状态
  6. hookItems 设置为 items,它是空的

这是第一次渲染,但我认为该原则适用于所有其他渲染;单击处理程序只能访问添加新项目之前的范围,因此,根据其具有的项目状态来设置 Hook 状态。

我对事情如何发生的假设可能是错误的,但它似乎与我所看到的一致。

那么,回到实际问题;如何根据某种处理程序的最新 Prop (而不是上次渲染时的 Prop )更新处于 Hook 状态的项目?

const { useState } = React;

const App = ({items, add}) => {
  const [hookItems, setHookItems] = React.useState([]);

  const handleClick = () => {
    add(Math.floor(Math.random() * 10));
    setHookItems(items);
  }


  return (
    <div>
      <p><span class="title">All Items: </span>{items.map(x => (<span>{x}</span>))}</p>
      <p><span class="title">Hook Items: </span>{hookItems.map(x => (<span>{x}</span>))}</p>
      <button onClick={handleClick}>Add</button>
    </div>
  );
}



const Root = () => {
  const [items, setItems] = useState([]);
  return (
    <div>
      <App items={items} add={item => setItems([...items, item])} />
    </div>
  )
}


ReactDOM.render(
  <Root />,
  document.getElementById('app')
);
.title { display: inline-block; width: 100px; text-align: right; margin-right: 20px;}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.6/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.6/umd/react-dom.production.min.js"></script>

<div id="app"></div>

最佳答案

问题是,每次渲染组件时,它都会获取其状态和 Prop 的一组值 - 但这些值直到下一次渲染才会更改。

所以如果我有这样的状态:

const [count, setCount] = useState(0);

如果我执行setCount(count + 1),它会排队一个新的渲染,其中count变量将为1,但它不会立即导致 count 变量变为 1。 (它不能 - const 变量无法更改)因此,如果我在设置后立即记录count,它仍然为零.

在您的示例中,存在一定程度的间接性,其中 setter 位于父组件中,由 add 函数触发,并且该值作为 prop 传递给子组件,但这并不'不要改变行为。

<小时/>

就设计而言,这里的问题是您正在使用“props to state”模式,这通常是一种反模式。你的组件通常不应该将 props 保存为状态,你应该直接使用 props。否则你会遇到 props 和 state 不同步的问题。

React 博客有一篇文章 You Probably Don't Need Derived State其中更详细地介绍了这一点。

关于javascript - Hook 状态落后于 prop 状态,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58752699/

相关文章:

javascript - 如何在 React 中删除项目?

reactjs - 更改 AWS Amplify Storage 中的私有(private)文件夹名称

javascript - Promise.all 错误 : Uncaught (in promise) TypeError: #<Promise> is not iterable

javascript - 如何在一次请求中按范围获取数据?

javascript - 不受控制的输入 React Hooks

javascript - this.state 与 useState 的 setTimeout

javascript - React Native - 函数捕获旧的钩子(Hook)值

javascript - Scrapy:POST 请求返回 JSON 响应(200 OK)但数据不完整

javascript - 表单验证,数百个复选框

javascript - expo AsyncStorage 方法不是函数