Sweet Brissie life

ブリスベンでのサトウキビ博士研究生活の甘くない備忘録

TypeError: Cannot read property XXX of undefined

Reactの勉強中にでてきたこのエラーメッセージとの奮闘記。勉強かねての投稿なので、理解が深まり次第更新予定です。

 

メッセージ自体の意味するところは、XXXというメソッド(?)を持つコンポーネント(?)がUndefinedですよ、てこと。

 

えぇ、そもそもこのメッセージ自体の理解がまだ浅いです。

 

とにかくUndefinedなのが問題なはずで、なんでそうなってしまっているのか?

調べていると、こんな記事に遭遇。

https://daveceddia.com/watch-out-for-undefined-state/

ざっくり訳してまとめると、

 

非同期でデータを取ってきて表示するような処理をしている場合、renderに渡るはずのstateがNullのままだとそのPropertyはUndefinedになってしまう、だからStateの初期化をConstructorでしてあげないといけませんよ。その時にPropTypesや場合によってはdefaultPropsも指定すべきで、その際にrender内で書けるDestructuring syntaxは便利ですよ。

 

...って感じなはずだけど、浅い理解なので訳も不安。

 

ここで出てきたPropTypes(とdefaultProps)に関して一つ注意しておきたいのが、少し古めの記事とかだと、PropTypesをreactからimportしてるけど、v15.5以降はprop-typesからだという点。

https://ja.reactjs.org/docs/typechecking-with-proptypes.html

コンポーネントのプロパティに対して、下記のようにどんどん型を割り当てるみたいです。

MyComponent.propTypes = {
// You can declare that a prop is a specific JS type.
//By default, these are all optional.
optionalArray: PropTypes.array,
optionalBool: PropTypes.bool,
optionalFunc: PropTypes.func,
optionalNumber: PropTypes.number,
optionalObject: PropTypes.object
// and more...
}

デフォルト値もdefaultPropsで似たように割り当てられる、とのこと。

 

正直まだ何言ってるのかあんま分からん。

 

ここまでで辛うじて理解できてるのは、Undefinedの原因としてStateの初期化ができていないことがあげられる、と。

 

 それからこの初期化のことを調べていて出てきたのが、thisのbind。

https://stackoverflow.com/questions/39176248/react-js-cant-read-property-of-undefined

https://www.codingame.com/playgrounds/8508/reactjs-constructor-tutorial

 

未だにreactにおけるthisの使い方がに自信がないのだけれど、同じコンポーネント内でプロパティを使いたい時にthisで参照する、みたいな感じのはず...

ただ、何らかのイベントとかのメソッドでthisを参照するときはメソッドにthisをconstructor内でbindしてやらないといけませんよ、ということらしい。

https://ja.reactjs.org/docs/handling-events.html

 一般的に、onClick={this.handleClick} のように () を末尾に付けずに何らかのメソッドを参照する場合、そのメソッドはバインドしておく必要があります。

 

へー、なるほどね!(棒)

 

...ちなみにここまで確認してみたけど自分の取り組んでいるReactの例では完全には解決できず。

その例ではDestructuring syntaxを使って初期化していたのだけれど、そのうちの一つのプロパティListに=[]を付けて明示的に初期化したらUndefinedのエラーはなくなった。しかし連動するアクション(テーブルをソートする)がエラーは出ないが機能もしないという状態に。

 

まだまだしばらく基本的な部分で苦戦しそう。