Objects are not valid as a React child. If you meant to render a collection of children, use an array instead - Error Solidity - React

£可爱£侵袭症+ 提交于 2020-04-30 09:18:07

问题


I am developing a document verification system with ReactJS and solidity - smart contract. I want to display the result of my smart contract's get().call() method on the frontend, with a popup or even with a simple text. The problem I am facing now is that when I am trying to display the response of the method, it throws to me that error:

Objects are not valid as a React child. If you meant to render a collection of children, use an array instead

Here is the code of my solidity contract:

pragma solidity ^0.5.0;
contract Proof1 {
  struct FileDetails {
    uint256 timestamp;
    string owner;
  }
  mapping(string => FileDetails) files;
  event logFileAddedStatus(
    bool status,
    uint256 timestamp,
    string owner,
    string fileHash
);

function set(string memory owner, string memory fileHash) public {
  if (files[fileHash].timestamp == 0) {
    files[fileHash] = FileDetails(block.timestamp, owner);

    emit logFileAddedStatus(true, block.timestamp, owner, fileHash);
  } else {
    emit logFileAddedStatus(false, block.timestamp, owner, fileHash);
  }
}

function get(string memory fileHash)
public
view
returns (uint256 timestamp, string memory owner)
{
  return (files[fileHash].timestamp, files[fileHash].owner);
}}

Here is .get().call() method inside onClick method:

onSubmitGet = async (event) => {
  event.preventDefault();
  const hash = document.getElementById("hash").value;

  this.state.design = await this.state.contract.methods
    .get(hash)
    .call({ from: this.state.address })
    .then((res) => this.setState({ result: res }));
};

And this is how I display the result with React:

const { result } = this.state;

<div>{result}</div>


回答1:


I don't know why you write the below code:

this.state.design = await this.state.contract.methods

The ReactJS doesn't have two-way-data-binding, The ReactJS is not like VueJS or Angular, for changing state you should use this.setState or useState. the this.state.design = never change anything of states.

Now for your question. set the initial state for the result like below:

this.state = {
  result: undefined,
};

Then in the JSX write it like below:

const { result } = this.state;

<div>
  {result && result.map((item, index) => (
    <div key={item.uniqueThing}>{item.title}</div>
  ))}
</div>

Actually, you don't need index, I just wanna aware you that you can have it. even you can write it better:

const { result } = this.state;

<div>
  {result && result.map(({ title, uniqueThing }) => (
    <div key={uniqueThing}>{title}</div>
  ))}
</div>

Note: you definitely should pass the key to the first JSX element of the map callback function return, and it should be unique, please do not use index it has a bad cost for ReactJS to handle it maybe sometimes fall into bad bugs.



来源:https://stackoverflow.com/questions/61282470/objects-are-not-valid-as-a-react-child-if-you-meant-to-render-a-collection-of-c

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!