javascript - ReactJS setState 来自异步回调

标签 javascript reactjs

嘿 ReactJs 社区,

我对 ReactJs 相当陌生,并且已经设置了我的第一个组件。现在我想更新特定事件的所有状态项。我通过 map() 循环每个状态项,并调用异步方法来确定要包含在状态中的值。 该方法通过回调函数返回 GET 数据。

updateItems: function() {
    var items = this.state.items;
    items.map(function(item, i) {
        checkConfirmation(item.hash, function(confirmations) {
            console.log("Item " + i + " has " + confirmations + " confirmations!");
            items[i].hash = item.hash + " (" + confirmations + ")";
            items[i].completed = true;
        });
    });
}

如何通过异步回调更新我的状态?

我尝试传入 this 作为 map() 中的第二个参数,并尝试在 map() 函数之后调用 setState,但是这是无法工作的,因为它将在回调中返回任何数据之前被调用。

感谢您花时间帮助我解决这个问题!

最佳答案

您可以对每个待处理的请求做出 promise 。使用 Promise.all 等待它们全部。并在所有请求完成后设置状态。

updateItems: function() {
    const items = this.state.items;

    const pending = items.map(item => new Promise(resolve => {
        checkConfirmation(item.hash, resolve)
    }))

    Promise.all(pending)
      .then(confirmations => confirmations.map((confirmation, i) => {
        const item = items[i]

        // copy items mutating state is bad
        return Object.assign({}, item, {
          completed: true,
          hash: `${item.hash}(${confirmation})`
        })
      }))
      .then(items => this.setState({ items })
}

UPD回调黑客

updateItems: function() {
    const items = this.state.items;
    let confirmations = []
    let loaded = 0

    const addConfirmation = i => confirmation => {
      confirmations[i] = confirmation
      loaded++;

      // if all were loaded
      if(loaded === items.length) allConfirmationsLoaded()
    }

    const allConfirmationsLoaded = () => {
        const newItems = confirmations.map((confirmation, i) => {
            const item = items[i]

            // copy items mutating state is bad
            return Object.assign({}, item, {
              completed: true,
              hash: `${item.hash}(${confirmation})`
            })
        })

        this.setState({items: newItems})
    }

    // for each item lauch checkConfirmation
    items.forEach((item, i) => {
      checkConfirmation(item.hash, addConfirmation(i))
    })
}

关于javascript - ReactJS setState 来自异步回调,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38251629/

相关文章:

javascript - 使用 JS 更改 svg 的 css 填充

javascript - erc20 认领 token 转移功能不起作用

javascript - 获取 data-* 属性的值并设置它们的列表

javascript - React 按钮中的无限循环

node.js - Flask 中的 ReactJS 服务器端渲染

javascript - React-Bootstrap 组件文档

javascript - webpack style-loader - 在 React 组件上导入不同的样式而不覆盖

javascript - 如何在 mocha 中测试 Uncaught Error ?

javascript - 如何在React Js中单独更新一个子组件

javascript - 如何用数字划分 div 并将结果值作为字体大小