質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
86.02%
Solidity

Solidityは、仮想通貨イーサリアム上で実行できるプログラミング言語。スマートコントラクトやDAppsなどの開発・実装に用いられます。コントラクト指向・高水準な言語のため、イーサリアム上で動作するEVM Codeに翻訳することが可能です。

Ethereum

Ethereum(イーサリアム)は、ビットコインに次いで時価総額が大きい仮想通貨もしくはそのブロックチェーン技術を指します。DApps やスマート・コントラクトの構築を目的としたプラットフォームであり、OSSで開発されています。

web3.js

web3.jsは、Ethereumのノードとローカルの通信を可能にできるJavaScript APIです。HTTPやIPCを使って通信を行い、gethを毎回起動せずにブラウザからコントラクトを実行できます。

React.js

Reactは、アプリケーションのインターフェースを構築するためのオープンソースJavaScriptライブラリです。

Q&A

解決済

ページ遷移ごとに毎回一度だけ「Unhandled Rejection (TypeError): Cannot read property 'methods' of null」とエラーが出る

sagi12
sagi12

総合スコア1

Solidity

Solidityは、仮想通貨イーサリアム上で実行できるプログラミング言語。スマートコントラクトやDAppsなどの開発・実装に用いられます。コントラクト指向・高水準な言語のため、イーサリアム上で動作するEVM Codeに翻訳することが可能です。

Ethereum

Ethereum(イーサリアム)は、ビットコインに次いで時価総額が大きい仮想通貨もしくはそのブロックチェーン技術を指します。DApps やスマート・コントラクトの構築を目的としたプラットフォームであり、OSSで開発されています。

web3.js

web3.jsは、Ethereumのノードとローカルの通信を可能にできるJavaScript APIです。HTTPやIPCを使って通信を行い、gethを毎回起動せずにブラウザからコントラクトを実行できます。

React.js

Reactは、アプリケーションのインターフェースを構築するためのオープンソースJavaScriptライブラリです。

1回答

0グッド

0クリップ

2646閲覧

投稿2020/10/25 06:43

#前提・実現したいこと
ReactとSolidityを使ってDAppsを作っています。(アドレスを入力するとそのユーザーの情報が表示されるプログラムです)
ブラウザでReactの動作確認をする際にエラーが発生しています。
エラーはページ遷移するごとに一度だけ表示されます。
毎回リロードをすると正常に動くようになるのですがこの問題を解決したいです。

#発生している問題・エラーメッセージ

エラーメッセージ Unhandled Rejection (TypeError): Cannot read property 'methods' of null // アカウント情報の読み込み 48 | viewRecord = async () => { 49 | const { contract, address } = this.state; > 50 | const result1 = await contract.methods.viewAccount(address).call(); | ^ 51 | const result2 = await contract.methods.viewAccount_Transaction(address).call(); 52 | console.log(result1); 53 | console.log(result2);

#該当のソースコード

react

1class Info extends React.Component { 2 3 4 constructor(props) { 5 super(props); 6 this.state = { 7 web3: null, 8 accounts: null, 9 contract: null, 10 name: null, 11 email: null, 12 address: "", 13 outputName: null, 14 outputEmail: null, 15 outputNumTransactions: 0, 16 outputReputations: 0, 17 outputNumSell: 0, 18 outputNumBuy: 0, 19 }; 20 } 21 22 componentDidMount = async () => { 23 try { 24 const web3 = await getWeb3(); 25 26 const accounts = await web3.eth.getAccounts(); 27 const networkId = await web3.eth.net.getId(); 28 const deployedNetwork = MarketApp.networks[networkId]; 29 const instance = new web3.eth.Contract( 30 MarketApp.abi, 31 deployedNetwork && deployedNetwork.address 32 ); 33 34 this.setState({ web3, accounts, contract: instance }); 35 } catch (error) { 36 alert( 37 `Failed to load web3, accounts, or contract. Check console for details.` 38 ); 39 console.error(error); 40 } 41 }; 42 43 // アカウント情報の読み込み 44 viewRecord = async () => { 45 const { contract, address } = this.state; 46 const result1 = await contract.methods.viewAccount(address).call(); 47 const result2 = await contract.methods.viewAccount_Transaction(address).call(); 48 console.log(result1); 49 console.log(result2); 50 const outputName = result1[0]; 51 const outputEmail = result1[1]; 52 const outputNumTransactions = result2[0]; 53 const outputReputations = result2[1]; 54 const outputNumSell = result2[2]; 55 const outputNumBuy = result2[3]; 56 this.setState({ outputName, outputEmail }); 57 this.setState({ outputNumTransactions, outputReputations, outputNumSell, outputNumBuy }); 58 }; 59 60 handleChange = (name) => (event) => { 61 this.setState({ [name]: event.target.value }); 62 }; 63 64 render() { 65 return ( 66 <div className="Info"> 67 <input 68 onChange={this.handleChange("address")} 69 placeholder="addressを入力" 70 /> 71 <button onClick={this.viewRecord}>閲覧</button> 72 73 <br /> 74 <br /> 75 76 {this.state.outputName ? <p>Name: {this.state.outputName}</p> : <p></p>} 77 {this.state.outputEmail ? ( 78 <p>Email: {this.state.outputEmail}</p> 79 ) : ( 80 <p></p> 81 )} 82 {this.state.outputNumTransactions ? <p>取引回数: {this.state.outputNumTransactions}</p> : <p></p>} 83 {this.state.outputReputations ? <p>評価: {this.state.outputReputations}</p> : <p></p>} 84 {this.state.outputNumSell ? <p>出品回数: {this.state.outputNumSell}</p> : <p></p>} 85 {this.state.outputNumBuy ? <p>購入回数: {this.state.outputNumBuy}</p> : <p></p>} 86 </div> 87 ); 88 } 89}

solidity

1export default Info; 2 3struct account { 4 string name; //名前 5 string email; //Emailアドレス 6 uint256 numTransactions; //取引回数 7 int256 reputations; //取引評価、大きい値ほど良いアカウント 8 bool resistered; //アカウント未登録:false, 登録済み:true 9 int256 numSell; //出品した商品の数 10 int256 numBuy; //購入した商品の数 11 } 12 13 address[] public users; // ユーザーのアドレス 14 15 mapping(address => account) accounts; 16 17// アカウント情報(個人情報) 18 function viewAccount(address user) 19 public 20 view 21 returns (string memory, string memory) 22 { 23 string memory _name = accounts[user].name; 24 string memory _email = accounts[user].email; 25 26 return (_name, _email); 27 } 28 29 // アカウント情報(取引) 30 function viewAccount_Transaction(address user) 31 public 32 view 33 returns ( 34 uint256, 35 int256, 36 int256, 37 int256 38 ) 39 { 40 uint256 _numTransactions = accounts[user].numTransactions; 41 int256 _reputations = accounts[user].reputations; 42 int256 _numSell = accounts[user].numSell; 43 int256 _numBuy = accounts[user].numBuy; 44 45 return (_numTransactions, _reputations, _numSell, _numBuy); 46 }

#補足情報(FW/ツールのバージョンなど)
Truffle v5.1.37 (core: 5.1.37)
Solidity - 0.5.2 (solc-js)
Node v14.2.0
Web3.js v1.2.1

以下のような質問にはグッドを送りましょう

  • 質問内容が明確
  • 自分も答えを知りたい
  • 質問者以外のユーザにも役立つ

グッドが多くついた質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

気になる質問をクリップする

クリップした質問は、後からいつでもマイページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

下記のような質問は推奨されていません。

  • 間違っている
  • 質問になっていない投稿
  • スパムや攻撃的な表現を用いた投稿

適切な質問に修正を依頼しましょう。

回答1

0

ベストアンサー

原因だけの回答になります。
処理の順番のくい違いで生じているエラーだと思います。
Reactでは、componentDidMountはレンダー直後に行われる処理です。
なので、処理は下記のコードの順番になり、

レンダー中の処理

viewRecord = async () => { const { contract, address } = this.state;   // ここではcontractがまだ、componentDidMountの処理の中でsetする定義のデータになっていない const result1 = await contract.methods.viewAccount(address).call();contract const result2 = await contract.methods.viewAccount_Transaction(address).call(); console.log(result1); console.log(result2); const outputName = result1[0]; const outputEmail = result1[1]; const outputNumTransactions = result2[0]; const outputReputations = result2[1]; const outputNumSell = result2[2]; const outputNumBuy = result2[3]; this.setState({ outputName, outputEmail }); this.setState({ outputNumTransactions, outputReputations, outputNumSell, outputNumBuy }); };

レンダー直後

componentDidMount = async () => { try { const web3 = await getWeb3(); const accounts = await web3.eth.getAccounts(); const networkId = await web3.eth.net.getId(); const deployedNetwork = MarketApp.networks[networkId]; const instance = new web3.eth.Contract( MarketApp.abi, deployedNetwork && deployedNetwork.address );    // ここではじめてcontractにデータの入ったstateがセットされる this.setState({ web3, accounts, contract: instance }); } catch (error) { alert( `Failed to load web3, accounts, or contract. Check console for details.` ); console.error(error); } };

以上の処理順になっているため、contractに期待しているmethodsプロパティが見つからずTypeErrorになっている。

Unhandled Rejection (TypeError): Cannot read property 'methods' of null

多分これが原因なんじゃないかなと思います。

リロードの定義はわからないですけど、多分一度componentDidMountが行われた後のリロードだから、エラーが起きてないんじゃないかと思います。

web3やSolidityに明るくないし、Reactも初心者なので、もし間違っていたらすいません。

投稿2020/10/25 07:42

編集2020/10/25 07:55
yuxki

総合スコア110

良いと思った回答にはグッドを送りましょう。
グッドが多くついた回答ほどページの上位に表示されるので、他の人が素晴らしい回答を見つけやすくなります。

下記のような回答は推奨されていません。

  • 間違っている回答
  • 質問の回答になっていない投稿
  • スパムや攻撃的な表現を用いた投稿

このような回答には修正を依頼しましょう。

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
86.02%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問

同じタグがついた質問を見る

Solidity

Solidityは、仮想通貨イーサリアム上で実行できるプログラミング言語。スマートコントラクトやDAppsなどの開発・実装に用いられます。コントラクト指向・高水準な言語のため、イーサリアム上で動作するEVM Codeに翻訳することが可能です。

Ethereum

Ethereum(イーサリアム)は、ビットコインに次いで時価総額が大きい仮想通貨もしくはそのブロックチェーン技術を指します。DApps やスマート・コントラクトの構築を目的としたプラットフォームであり、OSSで開発されています。

web3.js

web3.jsは、Ethereumのノードとローカルの通信を可能にできるJavaScript APIです。HTTPやIPCを使って通信を行い、gethを毎回起動せずにブラウザからコントラクトを実行できます。

React.js

Reactは、アプリケーションのインターフェースを構築するためのオープンソースJavaScriptライブラリです。