I have the following code in React:
export const useData= (previewMode: boolean) => {
if (previewMode) {
let [value_, loading, error]: any = useDocument(
doc(getFirestore(app), "settings", "content"),
{
snapshotListenOptions: { includeMetadataChanges: true },
},
);
const value: any =
value_?.data() === undefined ? { data: contentFile } : value_.data();
return { data: value, loading: loading };
}
return {data: contentFile, loading: false};
};
contentFile is a static JSON file that
The thing is I keep getting the following error:
src\lib\use-data.tsx
Line 11:41: React Hook "useDocument" is called conditionally. React Hooks must be called in the exact same order in every component render react-hooks/rules-of-hooks
Now I know the rules of react-hooks, but the problem is that I need a condition, without it, the useDocument hook will be always called and we will query the firestore and I don't want that.
I only want to load the document if the previewMode is on, is that possible?
This is how I use this hook: const { value, data } = useData(previewMode);
Thanks in advance
CodePudding user response:
You can't place a hook into a condition. They must be declared top level in the component, because React indexes them based on their order, then you use the declared result inside the condition.
In your case:
export const useData = (previewMode: boolean) => {
const document = useDocument(
doc(getFirestore(app), "settings", "content"),
{
snapshotListenOptions: { includeMetadataChanges: true },
}
);
if (previewMode) {
let [value_, loading, error]: any = document;
}
/* rest of component */
}
document
is now declared regardless of the condition, and React can track it.
If you don't want the firebase document to be called unless it's needed, consider not rendering current component unless previewMode
is true. e.g:
{ previewMode && <useData /> }
Which means in your component previewMode
is always true, so it can be simplified:
export const useData = (previewMode: boolean) => {
let [value, loading, error]: any = useDocument(
doc(getFirestore(app), "settings", "content"),
{
snapshotListenOptions: { includeMetadataChanges: true },
},
);
return { data: value.data(), loading };
};