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

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

新規登録して質問してみよう
ただいま回答率
85.37%
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

解決済

1回答

3631閲覧

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

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ライブラリです。

0グッド

0クリップ

投稿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

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.37%

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

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

質問する

関連した質問