How to fix "Uncaught Error: Objects are not valid as a React child" when passing objects, obtained from the blockchain, to the children components

How to fix "Uncaught Error: Objects are not valid as a React child" when passing objects, obtained from the blockchain, to the children components

我正在使用 Truffle、React 和 Web3.js 来编写 Dapp 的前端,但是当我尝试将变量传递给子组件时出现此错误:

Uncaught Error: Objects are not valid as a React child (found: object with keys {currentProvider, _requestManager, givenProvider, providers, _provider, setProvider, BatchRequest, extend, clearSubscriptions, options, transactionBlockTimeout, transactionConfirmationBlocks, transactionPollingTimeout, defaultChain, defaultHardfork, defaultCommon, defaultAccount, defaultBlock, methods, events, _address, _jsonInterface}). If you meant to render a collection of children, use an array instead. 

无论我使用 props 还是 useContext 传递,错误仍然存​​在。如果我摆脱了 ChildComponent,错误就不再存在了。

这是我传递给上下文的 3 个变量中的 console.log:

如你所见,web3是一个对象,accounts是一个数组,contract也是一个对象。

这是代码:

import React, { useState, useEffect } from 'react';
import getWeb3 from './getWeb3';
import BlockchainContext from './BlockchainContext';
import SimpleStorageContract from './contracts/SimpleStorage.json';
import ChildComponent from './components/ChildComponent'
import './App.css';

const App = () => {
  const [storageValue, setStorageValue] = useState(0);
  const [web3, setWeb3] = useState();
  const [accounts, setAccounts] = useState();
  const [contract, setContract] = useState();

  useEffect(() => {
    async function init() {
      try {
        const web3 = await getWeb3();
        const accounts = await web3.eth.getAccounts();
        console.log('accounts: ', accounts);
        const networkId = await web3.eth.net.getId();
        console.log('networkId: ', networkId);
        const deployedNetwork = SimpleStorageContract.networks[networkId];
        console.log('deployedNetwork: ', deployedNetwork);
        const contract = new web3.eth.Contract(SimpleStorageContract.abi, deployedNetwork && deployedNetwork.address);
        console.log('contract: ', contract);

        setWeb3(web3);
        setAccounts(accounts);
        setContract(contract);

      } catch (error) {
        alert(`Failed to load web3, accounts, or contract. Check console for details.`);
        console.error(error);
      }
    }

    init();
  }, []);

  return (
    <>
      {!web3 ? (
        <div>Loading Web3, accounts, and contract...</div>
      ) : (
        <div className="App">
          <BlockchainContext.Provider value={{web3, accounts, contract}}>
          <h1>Good to Go!</h1>
          <p>Your Truffle Box is installed and ready.</p>
          <h2>Smart Contract Example</h2>
          <p>If your contracts compiled and migrated successfully, below will show a stored value of 5 (by default).</p>
          <p>
            Try changing the value stored on <strong>line 42</strong> of App.js.
          </p>
          <ChildComponent />
          <div>The stored value is: {storageValue}</div>
          </BlockchainContext.Provider>
        </div>
      )}{' '}
    </>
  );
};
export default App;

这是 ChildComponent 的代码:

import React, { useContext } from 'react';
import BlockchainContext from '../BlockchainContext';

const ChildComponent = () => {
const blockchainContext = useContext(BlockchainContext)

  return (
      <div>This is the contract address {blockchainContext.contract}</div>
   );
}

export default ChildComponent;

我不明白这里发生了什么。

您不能直接在 React 中渲染对象或数组。检查这个问题:

import React, { useContext } from 'react';
import BlockchainContext from '../BlockchainContext';

const ChildComponent = () => {
const blockchainContext = useContext(BlockchainContext)

  return (
      Object.keys(blockchainContext.contract).map(key => {
         const contract = blockchainContext.contract[key]
         return( 
           <div> 
              <p> {key}: </p>
              <p> {contract /* assuming this is also not an object */ } </p> 
           </div>
         )
      })
   );
}

export default ChildComponent;