首页 文章

ReactJS状态未更新在setState回调中

提问于
浏览
3

我正在构建一个SIP电话,当前的调用由SipPhone类处理,并使用React显示在前端 . SipPhone有一个调用列表,用于触发React组件正在侦听的回调 .

主电话组件的初始状态包含空Immutable List

constructor(props) {
    super(props);
    ...
    this.state = {
        calls: List(),
    };
}

每当SipPhone更新时,此 calls 列表将通过回调触发的事件进行更新 .

handleUpdate = ({ calls }) => {
    const nextCalls = List(calls.map(call => {
      return new Call({ ... }) // Call is an Immutable Record
    });

    console.log(nextCalls.toJS()); // This prints the new list I want to save
    this.setState({ calls: nextCalls }, () => {
        console.log(this.state.calls.toJS()); // The list is empty here
    });
}

有时它会成功更新 calls 列表,而在其他时间 calls 没有't change. When I log the list before setting state, it is as it should be, however when logging in the setState callback it remains unchanged from it'先前的状态 . 有时候它有效,有时则不然 .

为了进一步测试这个,我添加了一个状态变量 tick ,每次我在这里设置状态时它都会递增 . 此更改准确地反映在回调中,而呼叫列表保持不变 .

我似乎无法弄清楚为什么会这样做 . 我实际上是使用普通数组而不是不可变列表开始这个项目,并遇到了同样的问题 . 我已经使用React已经有一段时间了,并且从未遇到过这个问题......有什么想法吗?

3 回答

  • 0

    事实证明,我的代码中的另一个函数是在某些情况下在调用componentWillUpdate之前设置状态,导致它忽略对setState的初始调用 . 这是错误的根源 .

  • 0

    我们之前遇到过这个问题,当时我们使用的是Immutable(而不是普通的JS)

    四处搜索,在反应文档中遇到了这个文档片段

    setState()不会立即改变this.state,但会创建挂起状态转换 . 调用此方法后访问this.state可能会返回现有值 . 无法保证对setState的调用进行同步操作,并且可以对调用进行批处理以获得性能提升 .

    除非使用 setState 的回调函数是真的强制要求,否则我建议去 componentDidUpdate .

  • 3

    我个人发现JsSIP库因为太多的方法和嵌套的回调而非常复杂 . 这与您在React应用程序中通常使用的内容非常不同 . 我和我的朋友曾经创建了一个名为 <SipProvider/> 的简单组件,它将所有JsSIP复杂性抽象出去,让我们通过配置道具和使用上下文方法来进行调用 . 我们终于在npm上发布了这个软件包 - 也可以从中受益!
    https://www.npmjs.com/package/react-sip

    如果你想在应用程序中存储一些数据's state but don' t想要使用redux / mobx / apollo客户端,那么名为recompose的库可能会有所帮助 . 它允许您将状态提升为更高阶的组件,从而将状态逻辑与其表示分开 . 我在一些项目中一直使用withState() / withReducer(),我很难想象再次使用 this.setState()

相关问题