【问题标题】:Comprhension about useState (React)关于useState的理解(React)
【发布时间】:2022-01-09 15:04:57
【问题描述】:

你能解释一下为什么这个简单的代码不能按预期工作吗?有一个名为“启动计时器”的按钮指向“计时”功能。我认为使用 setCount 会更新计数变量状态,但它每秒保持在 0。不是 useState 精确地用于更新变量吗?谢谢你的帮助 ! PS:在按钮中,我只是将 onClick 重命名为 clicAction 以在我的组件中使用它,但这根本不是问题。

import { Button } from './components/Button';
import { useState, useEffect } from 'react';

function App() {

  const [count, setcount] = useState(0);
  
 const chrono = () => {
   setInterval(() => {
    setcount(count +1);
    console.log(count);
   }, 
   1000);
 }

  return (
    <>
    <Button clicAction={chrono} nom="Start the timer"/>
    <p>{count}</p>
    </>
  );
}

export default App;

这是 Button 组件代码:

import { useState } from 'react';

export const Button = ({nom, clicAction}) => {

    return (
        <div>
            <button onClick={clicAction}>{nom}</button>
        </div>
    )
}

【问题讨论】:

  • 能否附上按钮组件
  • 当然 :) 问题已更新

标签: reactjs react-hooks use-state


【解决方案1】:

它不起作用的原因是因为您正在使用当前的count 值来确定下一个count 值。它可能无法按预期工作,因为正如 React official documentation 中所述,出于性能原因,React 倾向于异步调用 setState。因此对于状态,您不应该依赖它们的值来计算下一个状态。 〜反应。相反,您可能希望像这样将函数传递给 setCount 参数:

const chrono = () => {
  setInterval(() => {
    setcount(prevCount => prevCount + 1);
  }, 
  1000);
}

编辑

正如@Martin 所提到的,这种行为不是由异步引起的,而是由闭包引起的。所以我提到异步行为的解释在这种情况下没有正确使用。对于上述问题,在闭包的情况下使用函数作为setState 参数仍然是正确的。如果您正在寻找关闭解释,请参考@DrewReese 的回答。

【讨论】:

  • 该行为不是由异步引起的,而是由闭包引起的。
  • 啊,是的,这更有意义。谢谢
【解决方案2】:

这是间隔回调中count 状态的陈旧外壳。 count 的值永远不会是更新的参考。使用功能状态更新从之前的count 状态值正确更新。

如果您想记录状态更新,请在更新时使用useEffect 记录count 状态。

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

useEffect(() => {
  console.log(count);
}, [count]);


const chrono = () => {
  setInterval(() => {
    setCount(count => count +1);
  }, 1000);
}

【讨论】:

    猜你喜欢
    • 2021-09-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-21
    • 2023-02-08
    相关资源
    最近更新 更多