Code

2017年1月14日土曜日

React.js Component stateless から stateful に変更に伴う問題点

 今週、新しい機能を実装しているうちに、ある Component を Stateless から Stateful に変更しました。その Component を使っているところはあまり変わりがないと思いました。ただ、テストすると、ちょっとだけ不具合が発見しました。
 React.js は Component を更新する際に、もし _owner, key と component の type 変更がなければ、その Component を再利用して、HTML も再利用します。ここで、再利用される Component はもし State を持っている場合、その State は更新されません。もし何か State にある変数を更新したい場合、自分でやるしかないです。ここで、componentWillReceiveProps () 関数が利用して、setState を呼び出して、変数を更新します。
 componentWillReceiveProps では、setState を呼び出しても、実際は一回の Render にまとまります。かなり便利な関数ですね。

 ネットでは、毎回 key を変更すれば、React.js は毎回新しい Component を Mount するので、心配しないで済むとの方法もありましたが、新しい Component を作るにはまたいろいろコストがあるので、前のものを再利用したほうがいいでしょう。

 React.js の中に、Component を更新する方法は setState と新しい Props を渡す、forceUpdate() を呼び出す3種類しかないし、forceUpdate() はあまりおすすめできないし、setProps もないので、setState をうまく使わないといけないです。
 これでまたいつ Component は state を持つべきかとの原点に戻りました。Redux を使うと、store の中に state を置いて、その state と関係あるところは container を通じて、自動的に更新されますが、ただ、それは app 範囲の state の方です。state を持ってる component があまり向いてないようが気がしています。なぜなら、store は個別の component の state を持ってると、もし同じような component 複数ある場合、別の reference を使わないといけません。あるデータをある component のものと示すためです。
 この場合、Wrapper を使ったほうがいいようなが気がしています。state に入れるものは親 Component を持っていて、前の stateless の component も残したほうがいいでしょう。これで、state がいるかどうかによって、使い分けもいいでしょう。とにかく state を持ってない component が再利用しやすいから。ネットでは presentation component という design pattern もあります。こちらは render のみ提供する component と lifecycle 関数や、state を操作する関数を別の component に入れて、container component 両方分けて、どっちでも再利用しやすくするための方法です。
 それでは。

0 件のコメント:

コメントを投稿