React+Firebaseで「Error: Target container is not a DOM element.」

ReactとFirebaseで下記の記事を参考に、ログイン機能を作っていた(というか、Authの実装練習がてら新しくcreate-react-appをした)際に発生したエラーの対処法を説明します。なかなかググっても良さげな答えが日本語、英語ともになかったので、ここで記述しようと思います。

 [ReactでFirebase Authenticationを使う](https://qiita.com/zaburo/items/801bd288cec47bd28764)

同じ状況の人は参考にしてみてください。

## エラー内容

エラーメッセージはは以下の通りです。

`Error: Target container is not a DOM element.`

「ターゲットコンテナはDOM要素では無い？」となったので調べてみることに。
ただ、このエラーに関しての具体的な初心者でもわかるような説明のある記事が、記事冒頭でも言った通りなかったので、**firebase関連**でいろいろと検索をしていきました。

## 解決した方法
public(またはbuildなどのディレクトリ)の`index.html`の`<body>タグ`内に以下のコードを記述し、それ以外の`<body>タグ`内のコードを全て削除(orコメントアウト)する。

```index.html
<body>
  <div id="root"></div>
</body>
```

## 解決に至るまでの過程

(検索ワードはうろ覚えですが)`エラーメッセージ+firebase`で検索していると下記の記事を発見しました。

[gulp + webpack + reactの最小構成](https://qiita.com/uryyyyyyy/items/6d7d29499efbca8c618e)

「今回はReact+Firebaseだし、関係なさそうだな」と思いつつも、この記事を何となく上からさーっと目を通していくと、sourceという部分に目が止まり、そこを見ていて気付きました。以下に具体的な解決の過程を示します。

### 過程

firebaseを使う際に、

```
$ firebase init
```
でまずは初期設定を行うと思います。

その質問の中で、

```
? What do you want to use as your public directory?(public)
```
というものがあると思います。
これは、「公開するディレクトリとして使いたいものはどれですか？」という質問なのですが、ここでpublicを選択した場合はpublicを、それ以外のbuildなどを選択した場合はそのディレクトリの、`index.html`を開きます。

該当のindex.htmlを開くと`<body>タグ`の中身が下記のようなコードになっていませんか？

```index.html(筆者の場合はpublicフォルダ内)
<body>
    <div id="message">
      <h2>Welcome</h2>
      <h1>Firebase Hosting Setup Complete</h1>
      <p>You're seeing this because you've successfully setup Firebase Hosting. Now it's time to go build something extraordinary!</p>
      <a target="_blank" href="https://firebase.google.com/docs/hosting/">Open Hosting Documentation</a>
    </div>
    <p id="load">Firebase SDK Loading&hellip;</p>

    <script>
      document.addEventListener('DOMContentLoaded', function() {
        const loadEl = document.querySelector('#load');
        // // 🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥
        // // The Firebase SDK is initialized and available here!
        //
        // firebase.auth().onAuthStateChanged(user => { });
        // firebase.database().ref('/path/to/ref').on('value', snapshot => { });
        // firebase.messaging().requestPermission().then(() => { });
        // firebase.storage().ref('/path/to/ref').getDownloadURL().then(() => { });
        // firebase.analytics(); // call to activate
        // firebase.analytics().logEvent('tutorial_completed');
        // firebase.performance(); // call to activate
        //
        // // 🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥

        try {
          let app = firebase.app();
          let features = [
            'auth', 
            'database', 
            'messaging', 
            'storage', 
            'analytics', 
            'remoteConfig',
            'performance',
          ].filter(feature => typeof app[feature] === 'function');
          loadEl.textContent = `Firebase SDK loaded with ${features.join(', ')}`;
        } catch (e) {
          console.error(e);
          loadEl.textContent = 'Error loading the Firebase SDK, check the console.';
        }
      });
    </script>
</body>
```

これは`$ firebase init`をした際に、自動的に生成されたものなのですが、よくみるとなければならないとあるコードがありません。

それが`<div id="root"></div>`なのです。

### 考えられる原因
そもそも、`<div id="root"></div>`がなぜなかったのかが謎(わかる方教えてください🙏)なのですが、srcフォルダ内の`index.jsx`では以下のコードで指定された要素(**container**)のDOMにReactのコンポーネントをレンダリングします。

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

この時の、`ReactDOM.render`の中の第二引数`getElementById`が**container**と呼ばれるそうです。[公式ドキュメント](https://ja.reactjs.org/docs/react-dom.html)に書いてありました...w

ここで、もう一度最初に戻って、エラー文の内容を確認してみましょう。

`Error: Target container is not a DOM element.`

ここで繋がりましたね。

つまり、

**ターゲットのcontainer→document.getElementById('root')**

は

**DOM要素ではありません**

`index.html`にはrootというIDをもつ要素が無かったのに、`index.jsx`でレンダリングされようとしていた、だからエラーは起きたのでした。