TypeError:无法读取 Next.js 中 null 的属性(读取“useState”)

2023-12-25

我收到此错误消息TypeError: Cannot read properties of null (reading 'useState')当我在里面使用我的自定义挂钩时getStaticProps从 firebase firestore 获取数据。有人请帮我解决这个问题吗?

Challenges页面代码:

import Card from "../components/reusable/Card"
import { useCollection } from "../hooks/useCollection"

const Challenges = ({ challenges }) => {
  return (
        <div className="grid sm:grid-cols-2 lg:grid-cols-3 gap-6 justify-items-center mt-8">
          {challenges.map((challenge) => {
                return (
                  <Card key={challenge.id} card={challenge} />
                )
              })}
        </div>
  )
}

export default Challenges

export async function getStaticProps() {
  const { documents, isLoading } = useCollection("challenges", null, null, [
    "createdAt",
    "desc",
  ])

  return {
    props: {
      challenges: documents,
    },
  }
}

useCollection挂钩代码:

import { useEffect, useState } from "react"
import { collection, limit, onSnapshot, orderBy, query, where } from "firebase/firestore"

import { db } from "../firebase/config"

export const useCollection = (c, q, l, o) => {
  const [documents, setDocuments] = useState([])
  const [isLoading, setIsLoading] = useState(true)
  const [error, setError] = useState(null)

  useEffect(() => {
    let ref = collection(db, c)
    if (q) {
      ref = query(ref, where(...q))
    }
    if (o) {
      ref = query(ref, orderBy(...o))
    }
    if (l) {
      ref = query(ref, limit(l))
    }

    const unsubscribe = onSnapshot(ref, (snapshot) => {
      const results = []

      snapshot.docs.forEach(
        (doc) => {
          results.push({ ...doc.data(), id: doc.id })
        },
        (error) => {
          console.log(error)
          setError("could not fetch the data")
        }
      )
      // update state
      setDocuments(results)
      setIsLoading(false)
      setError(null)
    })

    return () => unsubscribe()
  }, [])

  return { documents, error, isLoading }
}

您可以使用useState或仅在 React 组件内的任何钩子,或自定义钩子钩子规则 https://reactjs.org/docs/hooks-rules.html说,并且getStaticProps https://nextjs.org/docs/basic-features/data-fetching/get-static-props两者都不是。另外,它仅在构建时运行,因此不会发送到浏览器:

如果导出一个名为getStaticProps(静态站点生成)从页面,Next.js 将在构建时使用返回的 props 预渲染此页面getStaticProps.

您可以将数据获取移至客户端并摆脱getStaticPros,像这样:

import Card from "../components/reusable/Card";
import { useCollection } from "../hooks/useCollection";

const Challenges = () => {
  const {
    documents: challenges,
    isLoading,
    error,
  } = useCollection("challenges", null, null, ["createdAt", "desc"]);

  if (isLoading) {
    return <p>Loading...</p>;
  }
  if (error) {
    return <p>Error happend</p>;
  }
  return (
    <div className="grid sm:grid-cols-2 lg:grid-cols-3 gap-6 justify-items-center mt-8">
      {challenges.map((challenge) => {
        return <Card key={challenge.id} card={challenge} />;
      })}
    </div>
  );
};

export default Challenges;

或者改造useCollection到一个普通的异步函数,里面没有任何钩子,并在里面使用它getStaticProps。但这似乎不是您想要的,因为您正在客户端上创建订阅等等。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

TypeError:无法读取 Next.js 中 null 的属性(读取“useState”) 的相关文章

随机推荐