TypeError: невозможно прочитать свойства null (чтение «useState») в Next.js

Я получаю это сообщение об ошибке TypeError: Cannot read properties of null (reading 'useState'), когда использую свои пользовательские перехватчики внутри getStaticProps для извлечения данных из хранилища firebase firebase. Кто-нибудь, пожалуйста, помогите мне с этим?

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.info(error)
          setError("could not fetch the data")
        }
      )
      // update state
      setDocuments(results)
      setIsLoading(false)
      setError(null)
    })

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

  return { documents, error, isLoading }
}
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
1
0
140
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вы можете использовать useState или любой хук только внутри компонента React, или пользовательский хук, как сказано в Rules of Hooks , и getStaticProps не является ни одним из двух. Кроме того, он запускается только во время сборки, поэтому не отправляется в браузер:

Если вы экспортируете функцию под названием getStaticProps (Генерация статического сайта) со страницы, Next.js предварительно отобразит эту страницу во время сборки, используя свойства, возвращаемые 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. Но не похоже, что это то, что вы хотите, так как вы создаете подписку на клиенте и все.

Для сбора вызовов я планирую удалить подписку с клиента. Итак, я думаю, что я должен получить данные внутри этого хука и вернуть их вместо обновления переменной состояния. Затем получите доступ к этим данным внутри файла getStaticProps.

r121 08.02.2023 12:03

Хорошо, я вижу. Держите меня в курсе, решена ли тема или нет :)

yousoumar 09.02.2023 08:59

Да, теперь это решено! Вместо того, чтобы вызывать хук внутри getStaticProps, я напрямую извлекаю данные из него.

r121 13.02.2023 18:01

Другие вопросы по теме