いしのなかにいる

*いしのなかにいる*

oops ! I am in rock !

Reactアプリを IE11 で表示すると 「オブジェクトは 'startsWith' プロパティまたはメソッドをサポートしていません。」 が発生する

create-react-app で作った ReactアプリをIE11で表示したら画面が真っ白に!

create-react-app で作った Reactアプリ をIE11で表示したら画面が真っ白になりました。

コンソールには以下のエラーが…

オブジェクトは 'startsWith' プロパティまたはメソッドをサポートしていません。

Possible Unhandled Promise Rejection (id: 0):
  TypeError: 未定義または NULL 参照のプロパティ '_currentElement' は取得できません

Chromeでしか動作確認をしていなかったのもあれなのですが、開発も終盤にきたタイミングでこれは困る〜。

解決までに半日ほど要してしまったので、次回またハマらないようにメモしておきます。

原因はsetState??

コンソールと睨めっこしたりデバッグコード埋め込んだりして見た結果、どうやら setState のタイミングでエラーが発生していることが判明

どうやら create-react-app で生成されるコードで startsWith() を呼び出しているんだけど、「IE11にはそんな関数が定義されていないよ」ってことが問題みたいです。

解決策

とりあえず、IE11にES6の新機能を使わせるには 『ポリフィル』 が必要になるそうです。

調べがついた解決策は、以下の2つ。

  1. es6-shimを使う
  2. babelのpolyfillを使う

1 es6-shim を使う

一つ目は es6-shim を使う、という方法

これは index.html で es6-shim のライブラリを読み込んであげるだけで良いようです。

  <head>
    
    <!--[if lt IE 10]>
    <script src="https://as.alipayobjects.com/g/component/??console-polyfill/0.2.2/index.js,es5-shim/4.5.7/es5-shim.min.js,es5-shim/4.5.7/es5-sham.min.js,es6-shim/0.35.1/es6-sham.min.js,es6-shim/0.35.1/es6-shim.min.js,html5shiv/3.7.2/html5shiv.min.js,media-match/2.0.2/media.match.min.js"></script>
    <![endif]-->
    <script src="https://as.alipayobjects.com/g/component/??es6-shim/0.35.1/es6-sham.min.js,es6-shim/0.35.1/es6-shim.min.js"></script>
    
  </head>

詳しくはコチラ(英文)

2 babelのpolyfillを使う

二つ目は babel の polyfill を使う方法。

babel-polyfill とか babel-runtime とか 色々用意されているようです。 (詳しくはこちらの記事が参考になりました。)

私はとりあえず babel-polyfill を選択しました。

導入はこんな感じ

# yarn の場合
$ yarn add babel-polyfill

# npm の場合
$ npm install --save babel-polyfill

後は index.js の先頭で import してやれば IE11 なんかでも ES6 の新しい機能が使えるようになります。

import 'babel-polyfill';
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';

ReactDOM.render(<App />, document.getElementById('root'));

これで IE11 でもReactアプリが(とりあえず)動くようになりました。

まとめ

今回は「とりあえず動くようにした」という感じ。

babel とか トランスパイル とか、その辺は全然理解できていないことが認識できました。

まぁその辺を考えたく無いからお手軽な create-react-app を使っている、というのもあるんですけどね。

とはいえ違うブラウザで動かすたびに(特にIE)で時間を取られるのもなんなので時間をとって勉強する必要があるな〜と感じました。