Как сделать асинхронный возврат цепочки обещаний в render () с помощью componentDidMount ()? - PullRequest
0 голосов
/ 06 января 2019

У меня есть кнопка в моем возвращении в моей функции рендеринга, которая вызывает функцию, которая инициирует цепочку обещаний, в результате которой результат обновляет переменную состояния. Однако значение не передается.

Я попробовал несколько попыток для componentDidMount (), но мне не повезло

Вот кнопка в моей функции рендеринга

<button onClick={this.addIPFSItem} className="btn btn-info btn-sm m-1">NewFile</button>

Это вызывает следующую функцию

addIPFSItem(){

var searchAddress = "0x9Cf0dc46F259542A966032c01DD30B8D1c310e05";

const contract = require('truffle-contract')
const simpleStorage = contract(SimpleStorageContract)
simpleStorage.setProvider(this.state.web3.currentProvider)


this.state.web3.eth.getAccounts((error, accounts) => {
  simpleStorage.deployed().then((instance) => {
    this.simpleStorageInstance = instance

    return this.simpleStorageInstance.getLength(searchAddress);
  }).then((accountLength) => {

    var items = []
    const ipfsPrefix = "https://ipfs.io/ipfs/";

    var i;
    for (i = 0; i < accountLength; i++) {
      var currHash = this.simpleStorageInstance.getBook(searchAddress, i, 
  {from: searchAddress});

      var currURL = ipfsPrefix + this.currHash;

      //Here I am printing the counter values, and it prints the correct 
      //amount
      console.log('itemhash ', i)
      items.push(currHash)
    }
    //I do not get the value of items[1] in the console, but an undefined
    //promise
    console.log('address URL ', items[1])

    //the state of ipfsHash is not updated correctly
    return this.setState({ipfsHash: items[1]});
  })
 })
}

По сути, я выполняю цепочку обещаний (подключаясь к web3) и получаю данные. Я думаю, что основная проблема заключается в том, что я вызываю асинхронную функцию в render (). Я не уверен, как это исправить с помощью componentDidMount ()

console.log('address URL ', items[1]) должен дать что-то вроде address URL 0x9Cf0dc46F259542A966032c01DD30B8D1c310e05. Однако вместо этого я получаю address URL Promise{<pending>}.

1 Ответ

0 голосов
/ 06 января 2019

Ваше this.simpleStorageInstance.getBook - это обещание, это означает, что оно выполняется асинхронно.

Чтобы получить его результат, вы должны использовать .then или новый синтаксис async/await. С помощью следующей функции ваш массив items будет заполнен правильными данными:

Вам придется поставить ключевое слово async перед именем родительской функции, если вы выберете это решение

for (i = 0; i < accountLength; i++) {
    items.push(await this.simpleStorageInstance.getBook(searchAddress, i, { from: searchAddress }))
}

Еще более короткий синтаксис подразумевал бы использование вашего необработанного массива учетных записей и map вместо его длины:

const items = myAccounts.map(async () => await this.simpleStorageInstance.getBook(searchAddress, i, { from: searchAddress }))
...