When I load my Nextjs page, I get this error message: "Error: Rendered more hooks than during the previous render."
If I add that if (!router.isReady) return null
after the useEffect
code, the page does not have access to the solutionId
on the initial load, causing an error for the useDocument
hook, which requires the solutionId
to fetch the document from the database.
Therefore, this thread does not address my issue.
Anyone, please help me with this issue!
My code:
const SolutionEditForm = () => {
const [formData, setFormData] = useState(INITIAL_STATE)
const router = useRouter()
const { solutionId } = router.query
if (!router.isReady) return null
const { document } = useDocument("solutions", solutionId)
const { updateDocument, response } = useFirestore("solutions")
useEffect(() => {
if (document) {
setFormData(document)
}
}, [document])
return (
<div>
// JSX code
</div>
)
}
useDocument hook:
export const useDocument = (c, id) => {
const [document, setDocument] = useState(null)
const [isLoading, setIsLoading] = useState(true)
const [error, setError] = useState(null)
useEffect(() => {
const ref = doc(db, c, id)
const unsubscribe = onSnapshot(
ref,
(snapshot) => {
setIsLoading(false)
if (snapshot.data()) {
setDocument({ ...snapshot.data(), id: snapshot.id })
setError(null)
} else {
setError("No such document exists")
}
},
(err) => {
console.log(err.message)
setIsLoading(false)
setError("failed to get document")
}
)
return () => unsubscribe()
}, [c, id])
return { document, isLoading, error }
}
3
Answers
If you make minimal representation, possible to try fix this error
You cannot call a hook,
useEffect
, your customuseDocument
, or any other after a condition. The condition in your case is this early returnif (!router.isReady) returns null
. As you can read on Rules of Hooks:Just remove that
if (!router.isReady) returns null
fromSolutionEditForm
and changeuseDocument
as below.The
if (!router.isReady) return null
statement caused the function to end early, and subsequent hooks are not executed.You need to restructure your hooks such that none of them are conditional:
and then to make
useDocument
avoid sending extra calls:and updated the effect with a check: