Reactアプリケーション開発テクニック を(大体)読んだので注意点をまとめる
正式名称はいまどきのJSプログラマーのための Node.jsとReactアプリケーション開発テクニック。長い。
この本はreactに限らず、electron, react native, flux, webpack, babel, websocket, expressなど、様々な技術を扱っていて、ベストプラクティスを学べるという点ではとても良い。ただ初版が2017年8月と古いのもあって、今の状況とは合わないところもある。第4章以外は読んだので注意点など、気づいたところを書いていく。
私の環境
- Ubuntu 18.04.3 LTS (Bionic Beaver)
- node v10.16.0
- npm 6.10.3
最初に
まず$ webpack
など、コマンドが使えないのはパスが通っていないせい。(npmのバージョンアップのせい?)
使う場合はexport PATH=${PATH}:./node_modules/.bin
でパスを通すか、npx <command>
に置き換えたほうが良い。
パッケージのアップグレード
サンプルコードのパッケージを最新版にしたい場合は
npx npm-check-updates -u
npm install
でアップデートができる。以下は全てパッケージが最新(2019/09/08)の時の話。
最新版reactで本書のコードを実行する場合
react ver16.3以降で
- componentWillMount
- componentWillRecieveProps
- componentWillUpdate
を使うと「廃止予定なので使わないでください」というwarningがでる*1( p146のコードなど)。 詳細は
Update on Async Rendering – React Blog を参照。
componentWillMountはconstructorへ。
「インチとセンチの単位変換コンポーネントを作ろう」(p160)について
inchToCm.jsにはバグがあって、cmChangedが*2.54じゃなくて/2.54(25行目)。
このアプリは上述のnpm-check-updates
でモジュールをアプデするとwebpackが通らないしなんかWARNもでる。
原因としてはbabelのアプデでオプションの指定が変わったことが挙げられる。
webpack.config.jsを
module.exports = { + mode: 'development', - presets: ['es2015', 'react'] + presets: ['@babel/preset-react']
のようにする*2。preset-envはなくてもバンドルが通る。なぜかわからん。npm install @babel/preset-react
でインストールしておく必要がある。WARNはmodule.exports.mode=’development’で消える。
webpackでバンドルすると今度は以下のような、廃止予定のライフサイクルです、というWARNが出る。
Warning: componentWillReceiveProps has been renamed, and is not recommended for use.
対策の詳細は公式を見てもらうのが良いが、この場合ではcomponentWillRecievePropsはgetDerivedStateFromPropsに移動するのが最良*3。
例:
static getDerivedStateFromProps(props, state) { if (props.value !== state.value) { return {value: props.value} } return null }
だがしかしcomponentWillReceiveProps
もgetDerivedStateFromProps
もバグを引き起こしやすいメソッドなので*4できるだけ使わない方法を考えたほうが良いらしい。
初心者なので理解するのに時間がかかったけど、引数の(props, state)は言い換えるなら(nextProps, currentState)で、わざわざcurrentStateを与えてるのはstaticメソッド内ではthisがundefinedになるから。
「汎用的な入力コンポーネントを作ってみよう」(p177)について
何の説明もなくprop-types
モジュールがでてくるが、これはreactが公式にサポートしてる型チェックモジュール。
以下の説明がわかりやすい。
アプリケーションが成長するにつれて、型チェックによって多くの不具合を見つけられるようになります。アプリケーションによっては、Flow もしくは TypeScript のような JavaScript 拡張を使ってアプリケーション全体の型チェックを行うことができるでしょう。しかしそれらを使用せずとも、React は組み込みの型チェック機能を備えています。コンポーネントの props に型チェックを行うために、特別な propTypes プロパティを割当てることができます。
詳細は 公式 を参照。
「DOMに直接アクセスする」(p185)について
ref={obj=> this.hoge = obj}
としてrefを利用するのは16.3から非推奨*5。以下のように編集することでモダンな書き方になる。
headタグ(reactとbabelのアップグレード)
<script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script> <script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script> <script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
constructor
this.userNameInput = React.createRef() this.pwInput = React.createRef()
renderメソッド
<input type='text' name='user' ref={this.userNameInput} ...> <input type='password' name='pass' ref={this.pwInput} ...>
createRefは.bind(this)しなくてもOKだった。というかbindしようとするとエラーが出る...なぜ?
「ReactコンポーネントでAjax通信を使う」(p191)について
componentWillMount
を使ってますよというエラーが出る。Ajax通信の場合はcomponentWillMount
じゃなくてcomponentDidMount
メソッドを使おう*6。中身は全く一緒でよい。
p284のコード
fs.renameだとコールバックがなんちゃらとエラーが出るので fs.renameSyncに変えると動く。もしくは以下のようにコールバック関数を書く。
fs.rename(req.file.path, des, (err) => { res.send('ファイルを受信しました<br/>' + `<img src="/pub/${fname}" />`) })
React Routerについて
React Router は今v5だが本書で使ってるv4とは互換性があるらしいので気にする必要はない。
websocket
websocketが急にでてきてわからなくなると思う。基本的な使い方はp324の下の通りだけど、
//「クライアント」がメッセージを受信した時の処理
は//「サーバー」がメッセージを受信した時
の誤植だと思う。多分...。
Wikiシステムを作ってみよう
react router で渡されるthis.props.matchには以下のような値が入ってる。参考までに。
自分のSNSを作ろう(p346)
あんまり関係ないけど、htmlのtitleタグがwikiになってました。
*1:https://ja.reactjs.org/blog/2018/03/27/update-on-async-rendering.html
*2:https://babeljs.io/docs/en/babel-preset-react#usage
*3:https://reactjs.org/blog/2018/03/27/update-on-async-rendering.html#updating-state-based-on-props
*4:https://reactjs.org/blog/2018/03/27/update-on-async-rendering.html#new-lifecycle-getderivedstatefromprops
*5:https://ja.reactjs.org/docs/refs-and-the-dom.html#creating-refs
*6:https://reactjs.org/blog/2018/03/27/update-on-async-rendering.html#fetching-external-data