Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 来自异步回调的ReactJS setState_Javascript_Reactjs - Fatal编程技术网

Javascript 来自异步回调的ReactJS setState

Javascript 来自异步回调的ReactJS setState,javascript,reactjs,Javascript,Reactjs,嘿,社区 我对ReactJs相当陌生,并且已经安装了我的第一个组件。现在我要更新特定事件的所有状态项。我通过map()循环每个状态项,并调用一个异步方法来确定要包含在状态中的值。 此方法通过回调函数返回GET数据 updateItems: function() { var items = this.state.items; items.map(function(item, i) { checkConfirmation(item.hash, function(con

嘿,社区

我对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;
        });
    });
}
如何从异步回调更新状态?

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


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

您可以对每个未决请求做出承诺。使用
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))
    })
}

checkConfirmation
是否返回某些内容?为什么您使用的是
map
而不是
forEach
?@ctrlplusb
checkConfirmation
是异步的,这意味着它无法返回某些内容,因为我们不知道数据何时可用。我使用了
map
,因为大多数ReactJS教程和官方网站也使用它。两者的优点是什么?只是映射通常用于将数组从一种类型转换为另一种类型。我认为它不适合您的用例。您的异步回调,只是为了让我知道我正确地阅读了您的代码,还是您没有排除代码,是“checkConfirmation”函数中的回调?因此,映射-对每个映射项进行异步调用。。是吗?@james emanon是的,我正在从Web服务器检查列表中每个项目的确认状态谢谢你的回答。我会在家里试一下,如果它有效的话,我会把它标记为正确的答案。不过,这个答案确实需要一个Promise库。我正在使用React Web和巴贝尔图书馆。是否有一种孤独不需要额外的依赖关系?实际上,主流浏览器都支持原生承诺。但你肯定可以使用回调。如果你讨厌未来的维护者:)你答案中的代码就像我希望的那样工作。我不知道这些承诺是本地支持的。这种溶液非常干净。非常感谢。