I created a Zustand Store with Persist so
import create from 'zustand';
import { devtools, persist } from 'zustand/middleware';
import Router from 'next/router';
import { getAuth, signInWithEmailAndPassword } from 'firebase/auth';
import { query, collection, getDocs } from 'firebase/firestore';
import { toast } from 'react-hot-toast';
import { firestoreDb } from 'src/libs';
import { AppState, Admin } from 'src/types';
export const useAppStore = create<AppState>()(
devtools(
persist(
(set) => ({
crimes: [],
isLoadingCrime: false,
isLoadingUser: false,
user: null,
// Methods
fetchCrimes: async () => {
set((state) => ({ isLoadingCrime: (state.isLoadingCrime = true) }));
const crimeQuery = query(collection(firestoreDb, 'crimes'));
await getDocs(crimeQuery)
.then((snapshot) => {
set((state) => ({
isLoadingCrime: (state.isLoadingCrime = false),
}));
set((state) => ({ crimes: (state.crimes = snapshot?.docs) }));
})
.catch((err) => {
set((state) => ({
isLoadingCrime: (state.isLoadingCrime = false),
}));
console.log(err);
});
},
}),
{
name: 'app-storage',
}
)
)
);
My Dashboard fetches the Crime from a function in the store called fetchCrime
import {
...
} from '@chakra-ui/react';
import Head from 'next/head';
import { useEffect } from 'react';
import AllCrimesTab from 'src/components/AllCrimesTab/AllCrimesTab';
import { useAppStore } from 'src/store';
const Dashboard = () => {
const { fetchCrimes } = useAppStore();
useEffect(() => {
fetchCrimes();
}, []);
return (
<Container maxWidth={'container.lg'}>
<Head>
<title>Crime-Report | Admin</title>
<meta name="crime-report" content="Report any crime.." />
<link rel="icon" href="/favicon.ico" />
</Head>
<HStack py={4}>
<Heading fontSize={'xl'} fontWeight={'black'}>
CrimeReport.
</Heading>
<Badge colorScheme={'purple'} rounded={'lg'}>
Admin
</Badge>
<Spacer />
<HStack>
<Menu>
<MenuButton>
<Avatar name="Admin Report" size={'sm'} />
</MenuButton>
<MenuList>
<MenuItem>
<Text>admin@crime-report.com</Text>
</MenuItem>
</MenuList>
</Menu>
</HStack>
</HStack>
<Box mt={7}>
<Tabs variant={'soft-rounded'} colorScheme={'purple'}>
<TabList>
<Tab fontSize={'sm'}>All Crimes</Tab>
{/* <Tab fontSize={'sm'}>Attended Crimes</Tab> */}
</TabList>
<TabPanels>
<TabPanel>
<AllCrimesTab /> // This components renders the Tab Below
</TabPanel>
</TabPanels>
</Tabs>
</Box>
</Container>
);
};
export default Dashboard;
I have my AppState like this
export type AppState = {
user: User | null;
crimes: QueryDocumentSnapshot<DocumentData>[] | [];
isLoadingCrime: boolean | undefined;
isLoadingUser: boolean | undefined;
fetchCrimes: () => void;
loginAdmin: (user: Admin) => void;
};
// AllCrimesTab
import {
...
} from '@chakra-ui/react';
import { useAppStore } from 'src/store';
const AllCrimesTab = () => {
const { isLoadingCrime, crimes } = useAppStore();
return (
<TableContainer border={'1px solid #EDF2F7'} rounded={'lg'}>
<Table variant="striped">
<TableCaption>CrimeReport. Data</TableCaption>
{isLoadingCrime ? (
<Thead p={4}>
<Tr>
<Th>
<Center>
<Spinner emptyColor="gray.200" color="purple.500" />
</Center>
</Th>
</Tr>
</Thead>
) : (
<Thead>
<Tr>
<Th>Email Address</Th>
<Th>Name</Th>
<Th>Phone Number</Th>
<Th>Crime</Th>
</Tr>
</Thead>
)}
<Tbody>
{crimes &&
crimes?.map((crime) => (
<Tr key={crime?.id}>
<Td>{crime?.data().email}</Td>
<Td>{crime?.data().name}</Td>
<Td>{crime?.data().phoneNumber}</Td>
<Td>{crime?.data().crime}</Td>
</Tr>
))}
</Tbody>
</Table>
</TableContainer>
);
};
export default AllCrimesTab;
On mounting the component, I get this error:
There was an error while hydrating. Because the error happened outside of a Suspense boundary, the entire root will switch to client rendering.
If I remove the persist on the store, it usually works.
I understand this is a conflict in the SSR sie of next, but I need a way to get this work.
Any help is appreciated.