简体   繁体   中英

How to define type with UseState and Firebase snapshot when you want to .map the data?

Relevant Code:

const [posts, setPosts] = useState([]);

 useEffect(
    () =>
      onSnapshot(
        query(collection(db, "posts"), orderBy("timestamp", "desc")),
        (snapshot) => {
          setPosts(snapshot.docs);
        }
      ),
    [db]
  );

 return (
 <div>
   {posts.map((post) => (
      <Post key={post.id} id={post.id} post={post.data()} />
    ))}
 </div>
)

The above code does run fine locally, but for deployment it seems like UseState being [] or undefined or null with.map is throwing an error.

Errors I've gotten so far:

1: Type 'QueryDocumentSnapshot[]' is not assignable to type 'never[]'.

So I tried altering UseState and snapshot as any, then we get error 2

2: Type error: Parameter 'post' implicitly has an 'any' type.

Then, I tried using String[] but that didn't work either

Then, I tried moving.map up (snapshot.docs.map) to get error 3

3: TypeError: Cannot read properties of null (reading 'map')

Any help would be greatly appreciated!

First, you can create an interface for your Post document. For example,

interface IPost {
  id: string
  title: string
  // other fields
}

Then you can use it with useState to define the type:

const [posts, setPosts] = useState<IPost>([]);

Additionally, you can set the data itself in state instead of the QueryDocumentSnapshot array:

setPosts(snapshot.docs.map((d) => ({ id: d.id, ...d.data() })) as IPost[])
return (
 <div>
   {posts.map((post) => (
      <Post key={post.id} id={post.id} post={post} />
    ))}
 </div>
)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM