webpackerのサンプルをparcelでつかったらautoloadが効かなかった
はじめに
parcelを使っていて動かすコードとしてwebpackerのreactのサンプルを使っていました。
その中で、parcelにはdefaultでautoloadの機能が備わっているのにloadされないという状態が起こりました。
ここでは原因とその対処法について書いていきます。
問題のコード
import React from 'react' import ReactDOM from 'react-dom' import PropTypes from 'prop-types' const Hello = props => ( <div>Hello {props.name}!</div> ) Hello.defaultProps = { name: 'David' } Hello.propTypes = { name: PropTypes.string } document.addEventListener('DOMContentLoaded', () => { ReactDOM.render( <Hello name="React" />, document.body.appendChild(document.createElement('div')), ) })
原因
以下のコードが問題でした。
document.addEventListener('DOMContentLoaded', () => { ReactDOM.render( <Hello name="React" />, document.body.appendChild(document.createElement('div')), ) })
autoloadはjsが再実行されるだけなので、addEventListener
で再度イベント登録しても、domがrenderされることはありません。
対処
まず、addEventListener
を使わずReactDOM.render
を即時実行するようにします。そうするとautoloadするたびにappendChild
されるので、getElementById
にして何個もdomが作られないようにします。html側にid要素をもつdivを一個作っておきました。
const mountNode = document.getElementById("app"); ReactDOM.render(<Hello name="React" />, mountNode);
jsのscriptタグがheadに書いてあったので、bodyの一番最後に変更してdivがある状態で読み込まれるようにもしました。
背景
Railsは基本scriptタグはheadに置くので、haedにおいても大丈夫なようにaddEventListener
を使った書き方になっているのだと思います。
まとめ
まだまだjsについては無知だなと感じました。