Objects are not valid as a React child when setState of an array at the end of a promise chain

时间:2019-01-07 13:43:27

标签: reactjs jsx es6-promise ethereum

I have a promise chain that creates an array. At the end of the chain, I want to copy that array to one of my state variables. However, I get "Objects are not valid as a React child"

I've tried various ways to chain the promise so that the state variable captures the array I want to put in it. If I put setState at the end of my function, it misses what I try to capture in the promise chain

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
  })
})

}

I expect my row in my state to change, but I get Objects are not valid as a React child

UPDATE: here is my render() function

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>
);
}

I'm not sure if my render() function is okay. Note that when I press the button <button onClick={this.addIPFSItem} className="btn btn-info btn-sm m-1">ShowList</button>, that calls the addIPFSItem() function. I don't know if I need a componentDidMount() as it happens after the initial rendering.

1 个答案:

答案 0 :(得分:0)

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">