ChatGPT解决这个技术问题 Extra ChatGPT

反应 setState 不更新状态

所以我有这个:

let total = newDealersDeckTotal.reduce(function(a, b) {
  return a + b;
},
0);

console.log(total, 'tittal'); //outputs correct total
setTimeout(() => {
  this.setState({ dealersOverallTotal: total });
}, 10);

console.log(this.state.dealersOverallTotal, 'dealersOverallTotal1'); //outputs incorrect total

newDealersDeckTotal 只是一个数字数组 [1, 5, 9] 例如但是 this.state.dealersOverallTotal 没有给出正确的总数但 total 呢?我什至设置了超时延迟,看看这是否解决了问题。任何明显的还是我应该发布更多代码?

除了答案中所说的之外,您还明确记录了状态的值,您调用 setState
@FelixKling 不,我在设置后调用 this.state 。我之前正在记录一个变量。不?
由于超时,您的 setState 确实在您记录状态后执行。我认为您在调试中要做的是将 console.log 部分放在超时内,将 setState 放在外面。
@FabianSchultz 你能解释一件事我当时没有得到。考虑这段代码:if(this.state.playersOverallTotal > 21){ console.log('bust'); this.setState({playerBusted: true}); } 当它超过 21 时,日志会触发,但状态不会改变,只有在数字再次增加时才会改变。例如,如果它达到 24,它不会设置状态,但是如果它达到 28,例如它会

F
Fabian Schultz

setState() 通常是异步的,这意味着在您 console.log 状态时,它尚未更新。尝试将日志放入 setState() 方法的回调中。状态改变完成后执行:

this.setState({ dealersOverallTotal: total }, () => {
  console.log(this.state.dealersOverallTotal, 'dealersOverallTotal1');
}); 

除此之外,OP 显式记录状态值他们调用 setState
这也适用于我,过去我使用过这个:`this.setState({someVar: newValue},function(){ console.log("force update}); '但由于某种原因它并不担心再有,当我更新上面描述的代码时它起作用了.知道为什么吗?
@Jozcar 应该也可以,语法不正确(缺少括号):this.setState({someVar: newValue},function(){ console.log("force update") });
imgur.com/Ku0OjTl 请告诉我应该怎么做才能摆脱这个问题。
我完全忘记了它是异步调用的事实,并且做了所有可能的代码更改,除了这个,在这里你拯救了我的大脑免于烧毁。谢谢
S
Siraj Alam

如果是钩子,您应该使用 useEffect 钩子。

const [fruit, setFruit] = useState('');

setFruit('Apple');

useEffect(() => {
  console.log('Fruit', fruit);
}, [fruit])

太好了,它适用于 useEffect。但为什么它需要一个?
useEffect 在每次重新渲染时运行,并且如果传入数组的项目是状态变量,则沙子已更改。因此,当水果发生变化并且组件重新渲染时,该 useEffect 将运行。
我在 useEffect 之外运行 setFruit 和 console.log 水果,它没有改变。 :/
M
Mahesh Joshi

setState 是异步的。您可以使用回调方法来获取更新的状态。

changeHandler(event) {
    this.setState({ yourName: event.target.value }, () => 
    console.log(this.state.yourName));
 }

D
Dev01

使用异步/等待

async changeHandler(event) {
    await this.setState({ yourName: event.target.value });
    console.log(this.state.yourName);
}

setState 不返回承诺,所以我不希望这会起作用。
M
Mokesh S

setState 在 react 中是异步的,所以要在控制台中查看更新的状态,请使用如下所示的回调(回调函数将在 setState 更新后执行)

this.setState({ email: 'test@example.com' }, () => {
   console.log(this.state.email)
)}

THANK YOU 就这样了,你得直接设置变量
M
Massimiliano Kraus

setState() 操作是异步,因此您的 console.log() 将在 setState() 改变值之前执行,因此您会看到结果。

要解决它,请将值记录在 setState() 的回调函数中,例如:

setTimeout(() => {
    this.setState({dealersOverallTotal: total},
    function(){
       console.log(this.state.dealersOverallTotal, 'dealersOverallTotal1');
    });
}, 10)

JavaScript 总是同步的。
@santoshsingh 你有一个误解。 API 调用、超时都是异步发生的。
正如您在上面提到的,javascript 是异步的——这是不正确的。它主要是同步的,在某些情况下它是异步的。 stackoverflow.com/questions/2035645/…
@santoshsingh。哦,那是我的一个错误。没有正确形成句子
非常巧妙地使用回调来确保在后续调用之前更新状态!
A
Arun Gopalpuri

多次设置反应状态时遇到问题(它始终使用默认状态)。关注此 react/github 问题对我有用

const [state, setState] = useState({
  foo: "abc",
  bar: 123
});

// Do this!
setState(prevState => {
  return {
    ...prevState,
    foo: "def"
  };
});
setState(prevState => {
  return {
    ...prevState,
    bar: 456
  };
});

像这样设置状态为我修复了它
z
zmechanic

对于一些复杂的代码,我也遇到了同样的情况,现有的建议对我没有任何帮助。

我的问题是 setState 是由其中一个组件发出的回调函数发生的。我怀疑调用是同步发生的,这完全阻止了 setState 设置状态。

简单地说,我有这样的事情:

render() {
    <Control
        ref={_ => this.control = _}
        onChange={this.handleChange}
        onUpdated={this.handleUpdate} />
}

handleChange() {
    this.control.doUpdate();
}

handleUpdate() {
    this.setState({...});
}

我必须“修复”它的方法是将 doUpdate() 放入 setTimeout 中,如下所示:

handleChange() {
    setTimeout(() => { this.control.doUpdate(); }, 10);
}

不理想,但否则它将是一个重要的重构。


这解决了我的问题,但我将 setState() 放在 setTimeout() 中。谢谢!
非常感谢伙计。您刚刚使我免于更多调试。
G
Gus T Butt

除了注意 setState 的异步特性外,请注意您可能有相互竞争的事件处理程序,一个执行您想要的状态更改,另一个立即撤消它。例如 onClick 在其父级也处理 onClick 的组件上。通过添加跟踪进行检查。通过使用 e.stopPropagation 来防止这种情况。


谢谢你离开这个。您的评论为我指明了正确的方向。我发现有问题的代码在冲突事件中被更新,然后在那个地方我使用 prevState 回调设置新状态,如上所述 @Arun Gopalpuri ``` this.setState(prevState=>{ return {...prevState, newProperty }}); ```
D
Dani Alcalà

如果您使用函数,则需要使用 UseEffect 来处理 setState 的异步(您不能像使用类时那样使用回调)。一个例子:

import { useState, useEffect } from "react";

export default function App() {
 const [animal, setAnimal] = useState(null);

 function changeAnimal(newAnimal) {
  setAnimal(newAnimal);
  // here 'animal' is not what you would expect
  console.log("1", animal);
 }

 useEffect(() => {
  if (animal) {
   console.log("2", animal);
  }
 }, [animal]);

 return (
  <div className="App">
  <button onClick={() => changeAnimal("dog")} />
 </div>
 );
}

第一个 console.log 返回 null,第二个返回 'dog'


P
Pravin Ghorle

只需在您的代码中添加 componentDidUpdate(){} 方法,它就会起作用。你可以在这里查看 react native 的生命周期:

https://images.app.goo.gl/BVRAi4ea2P4LchqJ8