React.jsがIE11で動かない問題を解決する

いまだにIE11を使う現場があったり、
個人もいたりするので、IE11でReact.jsを動かしてみたところ、
動かなかったので、解決方法を記録します。

#環境
* windows10
* Node.js v8.12
* React.js v16.8.6



#まずはそのまま

まずはcreate-react-appでReactプロジェクトを作って実行します。

```console
$ create-react-app ie11-trial
$ cd ie11-trial/
$ npm start
```

![image.png](https://qiita-image-store.s3.amazonaws.com/0/380290/21df5a17-541d-db70-1988-12379a0e412d.png)

おなじみのこの画面ですね！
ちなみにこのままIE11でも表示できます。

#適当にアプリを作る

とりあえずボタン押したらステータスが変わって、
画面表示が変わるアプリを作成します。

```jsx:src/App.js
import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';

class App extends Component {
  constructor(props) {
    super(props);
    this.state = {
      sample: {
        status: 'OK'
      },
    }
    this.handleClick = this.handleClick.bind(this);
  }

  // ボタンを押されたときによぶ関数
  // アロー関数にしておいてみる
  handleClick = () => {
    // stateからオブジェクトをES6に追加されたassignでコピーしてみる
    const sample = Object.assign({}, this.state.sample);
    // 適当に変更
    sample.status = sample.status === 'OK' ? 'NG' : 'OK';
    // セットする
    this.setState({
      sample: sample,
    });
  }

  render() {
    return (
      <div className="App">
        <header className="App-header">
          <img src={logo} className="App-logo" alt="logo" />

          {/* ボタンをおして、上の関数を呼んで、画面上の表示をかえる */}
          <button onClick={this.handleClick}>おしてね</button>
          {this.state.sample.status}

        </header>
      </div>
    );
  }
}

export default App;
```


#GoogleChromeで表示

![image.png](https://qiita-image-store.s3.amazonaws.com/0/380290/67b6580a-1d65-3cc5-0e39-b3f32b46e2bf.png)

ボタンを押すと、
ちゃんとOKとNGが入れ替わります。

#IE11で表示する

いよいよIE11で実行！

![image.png](https://qiita-image-store.s3.amazonaws.com/0/380290/41a74fe4-d5a5-d95b-962a-12082d013c0d.png)

画面表示はされるものの、
ボタンを押してもステータスが変化しません。

this.setStateや、
Object.assignでコピーしているとこでエラーが出ています。
つまりES6の記述などにIE11が対応していないのです。

#解決方法
足りないものはpolyfillをいれて補います。
polyfillとは、
「古いブラウザでも新しいWeb技術を使用できるように、
  既にあるWeb技術を用いて擬似的に実装すること」
とのことです。

調べたところ、いろいろ方法があって、
htmlに読み込んだり、babel使ったりありますが、
やってることはほぼ同じでした。

ここはReactの公式polyfillを使います。

* [react-app-polyfill](https://www.npmjs.com/package/react-app-polyfill)


#再チャレンジ

###インストール
```console
$ npm install react-app-polyfill
```

まずはpolyfillをプロジェクトにインストールします。

###読み込み
バンドルされるTOPのjsファイルにインポートします。
createReacAppで作ったWebアプリなら、
デフォルトだとsrc/index.jsになります。


```jsx:src/index.js

import 'react-app-polyfill/ie11';
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import * as serviceWorker from './serviceWorker';

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

```

一番上に、
import 'react-app-polyfill/ie11';
を記述するのみです。

※react-app-polyfill/ie9にするとie9～ie11までサポートしているようです。

###IE11にリベンジ！！

![image.png](https://qiita-image-store.s3.amazonaws.com/0/380290/aa2c874d-02fd-c637-f082-d9cd12d4403a.png)


・・・画面はNGになっててなんだか分かりにくいですが、
ちゃんと変化もするしエラーもなくなったので成功です。
（OKとNGを逆にしとけばよかった）

#感想

IEで動かなくていいやと割り切ってもいいのですが、
デモならともかく商用化していくのなら、
現状では、まだまだIE11の対応は必要かなと思っています。

#おまけ
そういえばEdgeでもうごくよね。。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/380290/3ac72e64-75ab-e786-3197-79ef1b81acc4.png)

よかった、動いた。

#おまけ2
safariでも動くよね？？

![image.png](https://qiita-image-store.s3.amazonaws.com/0/380290/ba2a116f-7f4e-8abe-dfbb-281ac7574286.png)

よかった（笑）

#参考
* [Polyfillって何?](https://azu.github.io/slide-what-is-ecmascript/slide/33.html)
* [Polyfillと共に歩んでいくために知っておきたいこと](https://www.mitsue.co.jp/knowledge/blog/frontend/201710/30_1154.html)
* [babel-polyfill 公式](https://babeljs.io/docs/en/babel-polyfill)
* [babel-polyfill github(旧)](https://github.com/babel/babel/tree/master/packages/babel-polyfill)