THUMBS SHIFT→

このブログは主に親指シフトを用いて書かれています

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
  }

だがしかしcomponentWillReceivePropsgetDerivedStateFromPropsもバグを引き起こしやすいメソッドなので*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には以下のような値が入ってる。参考までに。 f:id:arark:20190906230237p:plain

自分のSNSを作ろう(p346)

あんまり関係ないけど、htmlのtitleタグがwikiになってました。