※この記事は、プログラミング歴三ヶ月程度の初心者によって書かれています。ベテランの方は大目に見てもらえると助かります。同じように初心者の人は、私の言っていることを鵜呑みにしすぎず「?」と感じた点はすぐに検索するようにしてください。
#今回抜け出せなくなったこと
バックエンドはRails、フロントエンドはReactにTypeScriptを使って簡単なアプリを作ろうとしていました。
その時に、フロントエンド側でルーティング設定をしようと思い
$ npm install --save @types/react-router-dom
をターミナルで実行しました(セーブフラッグは無くても大丈夫だと思います。@typesというのはTypescript向けに型が付いたものなので、普通のJSでReact開発をしている人は必要ありません)。
そして、普通にコードで必要なものをインポートして使っていたのですが
Module not found: Can't resolve 'react-router-dom' in
というエラーに出くわします。
エラー文をそのまま検索したところ、TypeScript用だけじゃ無くて普通のreact-router-domもインストールした方が良いとのことだったので下のコマンドを実行しました。
$ npm install --save react-router-dom
そして、普通にコードを書き進め、npm startをしてlocalhostにアクセスすると画面のロードが終わらなくなりました。真っ白い画面で、コンソールにエラー表示もないまま、ずっとこのままです。
この問題を解決するのに、10時間以上のリサーチが必要になりました。
#環境
内容的にバージョンは関係ないので、JSONファイルを貼っておきます。
{
"name": "react_front_end",
"version": "0.1.0",
"private": true,
"dependencies": {
"@types/jest": "24.0.18",
"@types/node": "12.7.5",
"@types/react-router-dom": "^4.3.1",
"axios": "^0.19.0",
"react": "^16.9.0",
"react-dom": "^16.9.0",
"react-router-dom": "^4.3.1",
"react-scripts": "3.1.1",
"typescript": "^3.5.3"
},
"scripts": {
"start": "PORT=8000 react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
"eslintConfig": {
"extends": "react-app"
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
},
"devDependencies": {
"@types/react": "^16.9.2",
"@types/react-dom": "^16.9.0"
}
}
#解決策
原因は、Routeを使って、Routeを使っているコンポーネント自身を無限ループさせていたことでした。言葉だとうまく説明できないので、コードを表示します。
これが、ブラウザで表示されなかった時のコードです(長いので簡易化しています)。
import * as React from 'react';
import { BrowserRouter as Router, Route, Switch } from 'react-router-dom';
class App extends React.Component<{}, {}> {
render() {
return(
<div>
<Router>
<Switch>
<Route path="/" component={App} />
<Route path="/count" render={() => <Count name="fantastic!" />} />
<Route path="/history" component={History} />
</Switch>
</Router>
<h1>サインイン</h1>
<form onSubmit={e=>this.handleSubmit(e)} >
<input onChange={e=>this.handleEmailChange(e)} />
<input onChange={e=>this.handlePassChange(e)} />
<button type="submit">ログイン</button>
</form>
</div>
)
};
}
このコードで問題となっていたのは、Appコンポーネントの中でAppコンポーネント用のルートを設定している下のコードでした。
<Route path="/" component={App} />
解決策は単純でこの一行を削除してあげるだけです。
仕組みとしては最初にAppコンポーネントを読み込むのに、その中でそれ自身であるAppコンポーネントが読み込まれていて、それを読み込もうとするとまたAppコンポーネントが出てきて読み込んで…エラーになるということだと思います。
そもそも、元からAppコンポーネントは表示されているのでわざわざ、そこから設定しなくても大丈夫ですね。
#解決までの道のり
久しぶりに思いっきりハマってしまい、しかも一切エラーメッセージのないエラーだったので原因を特定するのにかなり時間がかかってしまいました。
最初は、アプリを閉じたり色々アップデートしてみたり、再起動したり、タブ閉じたりキャッシュ削除したりと色々していました。が、もちろんダメでした。
最終的に出てきた「page unresponsive」とReactを組み合わせて検索すると、ようやく解決策にたどり着けました、
エラーにハマった時は、とにかく違うアプローチを色々試してみること、そしてChromeのエラーであったとしても一緒に検索してみることが大事だなと思いました。