LoginSignup
9
4

More than 3 years have passed since last update.

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

Last updated at Posted at 2020-10-29

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

ReactでFirebase Authenticationを使う

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

エラー内容

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

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の最小構成

「今回は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の中の第二引数getElementByIdcontainerと呼ばれるそうです。公式ドキュメントに書いてありました...w

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

Error: Target container is not a DOM element.

ここで繋がりましたね。

つまり、

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

DOM要素ではありません

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

9
4
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
4