”missing dependencies"エラーの解消

現在、Firestoreを用いてデータベースへの情報の追加と取得を実現した。

しかし、URLの管理などを考えるとfirebase内の自動生成されたドキュメントIDが取得したい。

そう思って、テスト用のプロジェクトに無理やりこちらのサイトの内容を差し込んだ。

https://qiita.com/KOBA-RYOTA/items/eaa1c7d78cf6f2375256

結果以下のようなコードになる。

```
import './App.css';
import db from './firebase';
import { useState, useEffect, useRef } from "react";
import { collection, getDocs, onSnapshot, addDoc} from 'firebase/firestore';

function App() {
  const [posts, setPosts] = useState([]);
  const postData = collection(db, "posts");

  const addDataTitle = useRef();
  const addDataText = useRef();

  //add data to database

  const addData = () => {
    var date = new Date(Date.now());
    try {
      addDoc(postData, {
      title: addDataTitle.current.value,
      text: addDataText.current.value,
      timestamp: date,
    });
    console.log("Document written with ID:");
  } catch (e) {
    console.log("Error adding document:", e);
  }
  };
  

  useEffect(() => {
    //get data from database

    getDocs(postData).then((Snapshot) => {
      Snapshot.docs.forEach(doc => {
        const data = doc.data()
        console.log(doc.id);

        posts.push({
          title: data.title,
          text: data.text,
          id: doc.id,
        })

        
      })
      console.log(posts);
      // eslint-disable-next-line react-hooks/exhaustive-deps
      setPosts(posts);
    });

    

   // realtime update
    onSnapshot(postData, (post) => {
      setPosts(post.docs.map((doc) => ({...doc.data()})))})

  }, []);
  
  return (
    <div className="App">
      <div>
        {posts.map((post) => (
          <div key={post.id}>
            <h1>{post.title}</h1>
            <p>{post.text}</p>
            <p>{post.id}</p>
          </div>
        ))}
      </div>
      <div>
        <p>title:<input type="text" ref={addDataTitle}/></p>
        <p>text:<input type="text" ref={addDataText}/></p>
        <button onClick={addData}>add Data</button>
      </div>
    </div>
  );
}


export default App;

```

こうすると、useEffectの警告が出た。さらにsetPostsが動かなくなった。

よくよく見てみると、取得したデータを保管する"posts"にデータを直接書き換えていることになっている。

これはいけないって誰かが言っていたような気がする。

ということで、"posts"を"datas"へ変更する。
さらに、setPosts(posts)としてもIDがDBに反映されない原因がわからなかったが、
onSnapshotの自動更新が優先されてしまうことがわかったのでコメントアウトしたらうまく反映されてIDも表示されるようになった。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2971002/37383b20-49a9-3286-8355-17910f45a9cf.png)

相変わらず、依存関係の警告は消えない。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2971002/0fa4ebd7-e9ec-6bc1-b1ed-ba6b26138bbe.png)
これの原因はおそらく

```
  const postData = collection(db, "posts");
```

これがuseEffectの外で定義しているためだと考えられる。
データをDBに追加する際もこのpostDataを使用するので戻したくないので今回はエラーを解消しない。

本番のプロジェクトでは別のファイルにデータの記述と取得を記述しているのでそのとき警告が出ないか検証する。

実際に本番環境でこの方法を再現したらうまく行った。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2971002/19f7170b-c2af-19df-f6b0-05ad9bad9d9c.png)

本番でのコードは以下のようになっている。

```
import { collection, getDocs } from 'firebase/firestore';
import { useEffect, useState } from 'react';

import db from '../../firebase/firebase';
import Manga from '../multi_components/Manga';

const TopLanking = () => {
  const [posts, setPosts] = useState([]);

  useEffect(() => {
    // get data from databese
    const postData = collection(db, "posts");
    var newPosts = [];

    getDocs(postData).then((Snapshot) => {
      Snapshot.docs.forEach(doc => {
        const data = doc.data()
        newPosts.push({
          title:data.title,
          auther: data.auther,
          circle: data.circle,
          viewCount: data.viewCount,
          id: doc.id,
        })
      })
      setPosts(newPosts);
    });
  }, []);
  return (
    posts.map((manga) => (
      <Manga manga={manga} />
  ))
  )
}

export default TopLanking
```