Объекты недопустимы в качестве дочерних элементов React, когда setState массива находится в конце цепочки обещаний. - PullRequest
0 голосов
/ 07 января 2019

У меня есть цепочка обещаний, которая создает массив. В конце цепочки я хочу скопировать этот массив в одну из моих переменных состояния. Однако я получаю «Объекты недопустимы как дочерние элементы React»

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

addIPFSItem = () => {

   var finalItems = []
   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 movieItems = []


        var i;
       //WITHIN THIS LOOP extend the chain to add to movies
        for (i = 0; i < accountLength; i++) {

        var p = this.simpleStorageInstance.getBook(searchAddress, i, { from: searchAddress }).then((hashVal) => {
        return hashVal;
      })
      movieItems.push(p)
    }

    //return items
    return movieItems
  }).then((temp) =>{

    var i;
    var indexCounter=0;
    var arrayLength;
    arrayLength=temp.length

    for(i=0; i<arrayLength; i++){
      var p = temp[i].then((temp)=>{

        var ipfsPrefix = "https://ipfs.io/ipfs/";
        var ipfsURL = ipfsPrefix + temp;

        var movieItem = {id: indexCounter, poster_src: ipfsURL, title: "Some Title", overview: "blah blah"}
        indexCounter++

        return movieItem;
      }).then((item)=>{
        finalItems.push(item)
      }).then(()=>{
        if(finalItems.length == arrayLength ){

          //*******************************
          //Here is where I try to set state and get the error
          //*******************************
          this.setState({rows: finalItems})
        }
      })
    }

    return
  })
})

}

Я ожидаю, что мой row в моем состоянии изменится, но я получаю Объекты недействительны как дочерний элемент React

ОБНОВЛЕНИЕ: вот моя функция render ()

render() {

//Shows customer their account
var userAccount = "Your account is: " + this.state.account;

//Shows current IPFS _address
var currIPFS = "The IPFS address is: " + this.state.ipfsHash;


return (
  <div className="App">

    <table className="titleBar">
    <tbody>

      <h1>Interactive News</h1>
    </tbody>

    </table>

    <input style={{
      fontSize: 14,
      display: 'block',
      paddingTop: 8,
      paddingBottom: 8,
      paddingLeft: 14,
      width: "99%"
    }} onChange={this.searchChangeHandler} placeholder="Enter address for item lookup" />

 {this.state.rows}

    <main className="container">
      <div className="pure-g">
        <div className="pure-u-1-1">
          <h1>Your Image</h1>
          <p>This image is stored on IPFS & The Ethereum Blockchain!!!</p>
          <br />

          <font size="5">
          <span className="badge badge-info" dangerouslySetInnerHTML={{__html: userAccount}} />


          <br />
          <br />

          <span className="badge badge-light" dangerouslySetInnerHTML={{__html: currIPFS}} />

          <br />
          </font>

        <br />
        <br />

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


          <br />
          <br />

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

          <button onClick={this.handleDecrement}
          className="btn btn-primary btn-sm m-1"> Prev </button>

          <font size="5">
          <span className="badge badge-success">
            {this.state.index}
          </span>
          </font>

          <button onClick={this.handleIncrement}
          className="btn btn-primary btn-sm m-1">Next</button>

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

          <br/>


          <img src={`https://ipfs.io/ipfs/${this.state.ipfsHash}`} alt=""/>
          <h2>Upload Image</h2>
          <form onSubmit={this.onSubmit} >
            <input type='file' onChange={this.captureFile} />

            <input type='submit' />
          </form>
        </div>
      </div>
    </main>
  </div>
);
}

Я не уверен, что с моей функцией render () все в порядке. Обратите внимание, что когда я нажимаю кнопку <button onClick={this.addIPFSItem} className="btn btn-info btn-sm m-1">ShowList</button>, это вызывает функцию addIPFSItem(). Я не знаю, нужен ли мне componentDidMount(), как это происходит после первоначального рендеринга.

1 Ответ

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

React не может визуализировать объекты напрямую. Вы должны вернуть его, как реагируют компоненты DOM. Так как this.state.rows - это массив объектов, вам нужно пройти через него и обернуть каждый объект внутри значимого компонента DOM, например. li или div ..

<ul>
{
 this.state.rows.map((row, index) => {
  return (
       <li key={index}>{row.title}</li>
   )
 })
}
</ul>



<main className="container">
      <div className="pure-g">
...