【问题标题】:REACT.js Error: " Cannot read property ' methods ' of nullREACT.js 错误:“无法读取 null 的属性‘方法’
【发布时间】:2021-07-20 15:38:54
【问题描述】:

我正在学习在线教程以了解 DAPP 应用程序的工作原理,虽然我的代码与教程相匹配,但我收到一个错误,表明它们不匹配。我已经搜索了几个小时,虽然我可以找到类似的错误并且与我的匹配,但解决方案似乎不起作用。我希望这里的人可以看看,看看是什么导致了这个问题。

有2个按钮;一个用于存款,另一个用于提款。对于任何一个的 onClick 事件,我都在控制台中收到此错误(我目前在 try/catch 中将错误通过管道传送到控制台):

“错误,存款:TypeError:无法读取null的属性'methods'”

有没有人可以帮助我阐明这一点?我已经尝试联系教程的主人并在评论部分发表评论,但我没有得到回复。

这是 App.js 代码:

import { Tabs, Tab } from 'react-bootstrap'
import dBank from '../abis/dBank.json'
import React, { Component } from 'react';
import Token from '../abis/Token.json'
import dbank from '../dbank.png';
import Web3 from 'web3';
import './App.css';

//h0m3w0rk - add new tab to check accrued interest

class App extends Component {

  async componentWillMount() {
    await this.loadBlockchainData(this.props.dispatch)
  }

  async loadBlockchainData(dispatch) {
    //check if MetaMask exists, else push alert
    if(typeof window.ethereum!=='undefined') {

      await window.ethereum.enable()
      const web3 = new Web3(window.ethereum)
      const netId = await web3.eth.net.getId()
      const accounts = await web3.eth.getAccounts()

      if(typeof accounts[0] !=='undefined') {
        //check if account is detected, then load balance&setStates, else push alert
        const balance = await web3.eth.getBalance(accounts[0])
        this.setState({ account: accounts[0], balance: balance, web3: web3 })
        } else {
          //MetaMask not connected alert
          window.alert('MetaMask is detected, but not connected. Please accept the connection and login through MetaMask.')
          }

        //load contracts with try-catch error handling in case of error loading contracts
      try{
        //load Token contract
        const token = new web3.eth.Contract(Token.abi, Token.networks[netId].address)
        //load Bank contract and save address to variable
        const dbank = new web3.eth.Contract(dBank.abi, dBank.networks[netId].address)
        const dBankAddress = dBank.networks[netId].address
        //saved to state
        this.setState({token: token, dBank: dBank, dBankAddress: dBankAddress})
        } catch (e) {
          //contracts not loaded error
          console.log('Error', e)
          window.alert('Contracts are not deployed to the current network.')
          }
  
    } else {
      //MetaMask not detected alert
      window.alert('MetaMask is required to use this service. Please install MetaMask.')
      }

  }

  async deposit(amount) {

    //check if this.state.dbank is ok
    if(this.state.dbank!=='undefined'){
      try{
        await this.state.dbank.methods.deposit().send({value: amount.toString(), from: this.state.account})
      } catch (e) {
        console.log('Error, deposit: ', e)
      }
    }
  }

  async withdraw(e) {
    //prevent button from default click
    e.preventDefault()
    //check if this.state.dbank is ok
    if(this.state.dbank!=='undefined'){
      try{
        await this.state.dbank.methods.withdraw().send({from: this.state.account})
      } catch(e) {
        console.log('Error, withdraw: ', e)
      }
    }
  }

  constructor(props) {
    super(props)
    this.state = {
      web3: 'undefined',
      account: '',
      token: null,
      dbank: null,
      balance: 0,
      dBankAddress: null
    }
  }

  render() {
    return (
      <div className='text-monospace'>
        <nav className="navbar navbar-dark fixed-top bg-dark flex-md-nowrap p-0 shadow">
          <a
            className="navbar-brand col-sm-3 col-md-2 mr-0"
            href="www.pantheon.finance"
            target="_blank"
            rel="noopener noreferrer"
          >
        <img src={dbank} className="App-logo" alt="logo" height="65"/>
          <b> Pantheon Decentralized Investments</b>
        </a>
        </nav>
        <div className="container-fluid mt-5 text-center">
        <br></br>
          <br></br>
          <h1>Welcome to Pantheon Decentralized Investments</h1>
          <h2>Your connected address is:</h2>
          <h2>{this.state.account}</h2>
          <br></br>
          <div className="row">
            <main role="main" className="col-lg-12 d-flex text-center">
              <div className="content mr-auto ml-auto">
              <Tabs defaultActiveKey="profile" id="uncontrolled-tab-example">
                <Tab eventKey="deposit" title="Deposit">
                  <div>
                    <br></br>
                    How much would you like to deposit?
                    <br></br>
                    (Only one deposit of a min. 0.01 ETH allowable at a time)
                    <br></br>
                    <form onSubmit={(e) => {
                      e.preventDefault()
                      let amount = this.depositAmount.value
                      amount = Web3.utils.toWei(amount.toString(), 'ether') //converts amount to wei
                      this.deposit(amount)
                    }}>
                      <div className='form-group mr-sm-2'>
                      <br></br>
                        <input
                          id='depositAmount'
                          step="0.01"
                          type='number'
                          className="form-control form-control-md"
                          placeholder='amount...'
                          required
                          ref={(input) => { this.depositAmount = input }}
                        />
                      </div>
                      <button type='submit' className='btn btn-primary'>DEPOSIT</button>
                    </form>
                  </div>
                </Tab>
                <Tab eventKey="withdraw" title="Withdraw">
                  <br></br>
                    Would you like to withdraw your investment + interest earned?
                    <br></br>
                    <br></br>                  
                  <div>
                    <button type='submit' className='btn btn-primary' onClick={(e) => this.withdraw(e)}>WITHDRAW</button>
                  </div>
                </Tab>
              </Tabs>
              </div>
            </main>
          </div>
        </div>
      </div>
    );
  }
}

export default App;

【问题讨论】:

  • this.state.dbank 为空,但代码只防范undefined

标签: javascript html reactjs blockchain web3


【解决方案1】:

要检查空值或未定义值,请替换以下代码

if(this.state.dbank){
  //....your code
}

在您的代码中,您只检查“未定义”值,而 this.state.dbank 在调用 this.loadBlockchainData() 方法后初始化为 null,它不会进入 if 块 if(typeof accounts[0] !=='undefined') {} 并且仍然处于初始 null 状态

【讨论】:

  • 对不起,我真的很新,所以我可能不理解你,但我会努力的。所以你是说问题是因为我在应该检查 null 时检查了“未定义”?在这种情况下,我应该将第 60 行的 IF 语句从: if(this.state.dbank!=='undefined'){ } 改为 this 吗? if(this.state.dbank){ }
  • 你应该同时检查 null 和 undefined,我已经为你提供了上面的例子
  • 是的@MichaelMorris,一旦你用 if(this.state.dbank) 条件替换,你就不会出现上述错误。
  • 谢谢。我将对此进行更多研究,以更好地理解它,再次感谢您的帮助。我认为这停止了错误。但我可能发现了另一个问题。出于某种原因,我没有在 metamask 中获得批准提示。我之前在将 metamask 连接到我的 ganache 和通过 web3 时遇到了一些问题,所以我认为我需要重新执行所有这些步骤。对于像我这样的初学者来说,这可能是一个雄心勃勃的项目。 :-)
  • 欢迎..继续学习..一切顺利。请为答案投票
猜你喜欢
  • 2015-07-01
  • 1970-01-01
  • 2022-07-06
  • 2022-01-16
  • 1970-01-01
  • 2021-11-07
  • 2017-06-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多