如何让setState立即生效?

问题描述 投票:0回答:1

在我的代码中,有一个输入元素。

<input id="input" className="ml-2" type="number" name="Qty" min="1" max="999" value={qty} onChange={(e) => {changeQty(e)}}/>

而onChange处理程序是:

    const changeQty = (e) => {
        setQty(e.target.value);
        console.log(qty);
    }

所以我想不管我在输入栏里输入什么 都会在控制台里打印出来 但事实上是有延迟的。

例如,默认值是1,然后我输入2,那么1就会被打印出来,然后我输入3,那么2就会被打印出来。然后我输入3,那么2就会被打印出来。打印出来的数字是我之前输入的数字,而不是当前的数字,如下图。

enter image description here

谁能告诉我如何消除延迟?

我看了 使用状态集方法不能立即反映变化但还是无法解决。

我试了下面的代码,如答案所示。

useEffect(() => {
    setQty(document.getElementById("input").value)
}, [qty]);

但错误 ReferenceError: Cannot access 'qty' before initialization 发生。

谢谢!我的代码中有一个输入元素

javascript reactjs
1个回答
4
投票

从目前的问题来看,很难说,但我假设你正在写一个函数组件,并且使用了一个 useState 钩。也就是说,在某处上面的 changeQty 你有类似的东西。

const [qty, setQty] = useState(0);

如果是这样的话,那么答案就直接在上面的qty赋值里了。qty 的赋值中设置,当你调用 useState 钩子的值,并且在执行期间不会改变。

setQty 不更新qty的值. 它更新了内部状态,这将触发重新渲染。这意味着 下次 您的渲染函数被调用。qty 会有你使用的值。

但对于函数的其他执行。qty 将保持它在 useState 被调用。

如果你需要新的 qty 在你的函数的同一个迭代中,你可以将其捕获为一个新的变量。

const [qty, setQty] = useState(0);
let updatedQty = qty;

const changeQty = (e) => {
  updatedQty = e.target.value;
  setQty(updatedQty);
  console.log(updatedQty);
}

1
投票

this.setState() 有两种形式可以帮助你。

函数式

this.setState((prevState, props) => ({}))

回调表格

this.setState(nextState, () => {
    // instructions for immediately-after the state update
})

听起来,你可以在这里使用回调形式,将一些计算推迟到回调中。

另外,如果外面是战区的话,你可以把这些连锁起来。

this.setState(nextState, () => {
    this.setState(nextState, () => {
        this.setState(nextState, () => {
            // you can do this, but probably don't
        })
    })
})

但是,请注意正在发生的极端缩进现象;这让人联想到回调地狱和Promise圣诞树地狱。


0
投票

问题是setQty是异步的,试试这个。

useEffect(() => {
console.log(qty);

}, [qty])。

你通常会在这个console.log中得到当前值.在你的代码中,你的console.log可能会在状态更新之前执行,因为 setQty 不同步


0
投票

由于你没有分享你所有的代码,所以很难准确回答你的问题,但看起来你使用了React的钩子,所以我创建了一个正确使用钩子设置的示例 qty 状况,并记录当前 qty 价值。

const Quantity = function() {
  const [qty, setQty] = React.useState(0);
  const changeQty = (e) => {
    setQty(e.target.value);
  };
  React.useEffect(() => {
    console.log(qty);
  }, [qty]);
  
  return (
      <input id="input" className="ml-2" type="number" name="Qty" min="1" max="999" value={qty} onChange={(e) => {changeQty(e)}}/>
  );
};
ReactDOM.render(<Quantity />, document.getElementById("app_root"));
<head>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.0/umd/react.production.min.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.0/umd/react-dom.production.min.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/babel-standalone/6.26.0/babel.min.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/babel-core/5.8.25/browser-polyfill.min.js"></script>
</head>

<body>
  <div id="app_root"></div>
</body>
© www.soinside.com 2019 - 2024. All rights reserved.