ReactにcomponentDidReceivePropsが欲しいと思ったけれど今回は無くても解決しました
React.Componentのライフサイクル関数には
- 新しいpropsを引数で受け取る
componentWillReceiveProps
- 新しいpropsとstateを引数で受け取る
componentWillUpdate
- propsとstateが更新された後に呼び出される
componentDidUpdate
があります.
ここでクラス内で複数propsを参照する処理を行っていると, propsを更新されてから処理を行いたい時があります.
ReactのcomponentWillReceiveProps内ではまだpropsは反映されていない - 脳汁portal
例えばpropsの内容に合わせてWindowOrWorkerGlobalScope.setInterval()を行うときなどですね.
componentWillReceiveProps
で引数でpropsを渡されるのだからそれを参照すれば良いのでは?
と思うかもしれません.
しかし,
それだとクラス内のpropsを参照するコードと,
引数のpropsをコードが同じことを行っているのにも関らず,
参照する先が分かれただけでコードが分かれてしまいます.
ではcomponentDidUpdate
を使えばpropsが更新されていて丁度良いのでは?と思いました.
しかしこれには罠がありcomponentDidUpdate
の内部でsetState
を呼び出すと無限にcomponentDidUpdate
が呼び出されて無限ループになります.
そこで私はcomponentDidReceiveProps
が欲しいと思いました.
stateの更新は見ずに,
propsが更新された時だけ呼び出されるメソッドです.
さっそくググってみたところ,
2015年から欲しいと言われていたようです.
componentDidReceiveProps Please · Issue #3279 · facebook/react
しかし残念ながら要らないということでcloseされています.
issueに載ってるupdateするべきかどうかをフラグとして書くなどの回避策などを見ていて,
今回の場合はsetState
使わなくても解決すると気がつきました.
setState
で保存したかったのはsetInterval
の返す値で,
これを状況に応じてclearしたかったのですが.
この値は描画に一切関らないので,
stateに持たせないで普通のクラスのプロパティとして持てば解決することに気がつきました.
これをcomponentDidUpdate
の内部で更新すればstateではないので再度呼び出されることも無くて解決ですね.
Reactだからと言って何でもかんでも状態をstateに持たせる必要はないということですね.
しかし今回はこれで解決しましたが,
setState
をガッツリ使いつつクラス内部のpropsを参照する処理をpropsが更新された時に呼び出したい時はどうすれば良いんでしょう.
やはりstateの変更には反応せずにpropsの変更だけに反応するcomponentDidReceiveProps
は需要があるのでは?
それともcomponentWillReceiveProps
の内部でthis.props = nextProps
しても良いのでしょうか?
すごい行儀が悪そうだからやりたくないんですが.