当前位置: 首页 > 知识库问答 >
问题:

Reactjs中是否有setState()的同步替代方案

荣德厚
2023-03-14

根据文件中的说明:

setState()不会立即改变this.state,但会创建挂起的状态转换。调用此方法后访问this.state可能会返回现有值。

对setState的调用不能保证同步操作,可能会为了提高性能而对调用进行批处理。

因此,由于setState()是异步的,因此无法保证其同步性能。是否有同步的setState()替代方法。

例如

//initial value of cnt:0
this.setState({cnt:this.state.cnt+1})
alert(this.state.cnt);    //alert value:0

因为警报值是以前的值,所以什么是替代方案,将给予警报值:1使用setState()

Stackoverflow上有几个问题与这个问题相似,但没有我能找到正确答案的地方。

共有3个答案

孔和畅
2023-03-14

如果需要这样做,我建议在setState函数中使用回调函数(我也建议使用setState函数)。

状态更新后将调用回调。

例如,你的例子是

//initial value of cnt:0
this.setState(
    (state) => ({cnt: state.cnt+1}),
    () => { alert(this.state.cnt)}
)

根据这里的留档:https://facebook.github.io/react/docs/react-component.html#setstate

注意:官方文档说,“通常我们建议使用componentDidUpdate()来代替这种逻辑。”

晋言
2023-03-14

您可以将setState包装在返回promise的函数中,然后将此函数与wait关键字一起使用,以使代码等待状态被应用。

就个人而言,我永远不会在实际代码中这样做,相反,我只会将状态更新后希望执行的代码放在setState回调中。

这是一个例子。

class MyComponent extends React.Component {

    function setStateSynchronous(stateUpdate) {
        return new Promise(resolve => {
            this.setState(stateUpdate, () => resolve());
        });
    }

    async function foo() {
        // state.count has value of 0
        await setStateSynchronous(state => ({count: state.count+1}));
        // execution will only resume here once state has been applied
        console.log(this.state.count);  // output will be 1
    }
} 

在foo函数中,wait关键字导致代码执行暂停,直到解决了由setStateSynChronous返回的promise,这只发生在调用传递给setState的回调时,这只发生在状态已应用。因此,只有在应用了状态更新后,执行才会到达console.log调用。

异步/等待的文档:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/await

李华茂
2023-03-14

正如您从留档中读到的,没有同步替代方案,原因是性能提高。

但是,我假设您希望在更改状态后执行操作,您可以通过以下方式实现:

class MyComponent extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
     x: 1
    };
    
    console.log('initial state', this.state);
  }
  
  updateState = () => {
   console.log('changing state');
    this.setState({
      x: 2
    },() => { console.log('new state', this.state); })
  }
  
  render() {
    return (
      <div>
      <button onClick={this.updateState}>Change state</button>
    </div>
    );
   
  }
}

ReactDOM.render(
  <MyComponent />,
  document.getElementById("react")
);
<div id="react"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
 类似资料:
  • 问题内容: 根据文档中的解释: setState()不会立即更改this.state,但会创建一个挂起的状态转换。调用此方法后访问this.state可能会返回现有值。 无法保证对setState的调用的同步操作,并且可能会为提高性能而批量调用。 因此,由于是异步的,因此无法保证其同步性能。是否有替代方案是合时的。 例如 由于该值是先前的值,因此使用的替代方案是什么。 关于Stackoverflo

  • 我刚刚发现,在react函数都是异步的,或者在调用它的函数完成后调用。 现在这两样东西很难消化 在博客中,函数是在函数内部调用的,但是触发函数的原因并不是被调用函数所知道的。 他们为什么要让异步,因为JS是单线程语言,而且这个setState不是WebAPI或服务器调用,所以只能在JS的线程上完成。他们这样做是为了使重新呈现不会停止所有事件侦听器和其他东西,还是有其他设计问题。

  • 编辑:这是一个副本,请参阅此处

  • 问题内容: 如果我使用Oracle,则有一个可用于创建层次查询的关键字。当前,我在一个项目上使用MySQL,我想知道MySQL中是否有替代方法? 我尝试谷歌,但无济于事。我想要实现的是通过一个查询从数据库中获取一棵树。涉及两个表: 和。后者包含两个ID,一个是,另一个是。因此,它基本上是一个自联接,我可以使用该模型创建图。实际上,它目前仅用于创建树,但是将来可能会改变。但无论哪种情况,我都想拥有的

  • 问题内容: py2exe是否有替代品? 问题答案: cx_Freeze是跨平台的,并且具有相同的功能,或者您可以使用py2app,它仅在Mac上有效。

  • 问题内容: 我试图了解某些“魔术”行为的根本原因,但我无法完全解释,而从阅读ReactJS源代码中看不出来。 当响应输入中的事件而同步调用该方法时,所有操作均按预期进行。输入的“新”值已经存在,因此DOM实际上并未更新。这是非常理想的,因为这意味着光标不会跳到输入框的末尾。 但是,当运行具有完全相同结构但 异步 调用的组件时,输入的“新”值似乎不存在,从而导致ReactJS实际触摸DOM,这将导致