I'm using Zustand for state management (although I'd imagine the same principle applies to all state management libraries such as Redux or Recoil). I've thought about and tried:
getStaticProps()
and using useEffect()
to push the data to state during the first page render. The problem is that the data isn't pushed to state until that specific page is loaded. I don't want to use getInitialProps()
, as it's being deprecated.useEffect()
. This way I could freely populate the pages by using the data from state, and it only required one API call. Example below:function MyApp({ Component, pageProps }) {
// Load data from api with SWR
const fetcher = (url) => fetch(url).then((res) => res.json());
const { data, error } = useSWR(
"https://example.com/api",
fetcher
);
// Get data setter from state
const setData = useStore((state) => state.setData);
// When data is fetched successfully, populate state with data
useEffect(() => {
if (data) {
setData(data);
}
}, [data]);
if (error) return "Error has occured";
if (!data) return "Loading...";
return (
<Layout>
<Component {...pageProps} />
</Layout>
);
}
export default MyApp;
Are there better ways to fetch data and use it to populate state on the first time the app is loaded? What are the best practices?
I got it working the right way using Zustand context provider and initializing it using Nextjs pageProps
and getStaticProps()
.
_app.js
function MyApp({ Component, pageProps }) {
const createStore = initStore(pageProps.initZustand);
return (
<Provider createStore={createStore}>
<Component {...pageProps} />
</Provider>
);
}
export default MyApp;
store.js
export const { Provider, useStore } = createContext();
let store = {
names: ["Name 1", "Name 2", "Name 3"],
random: [],
setRandom: (data) => {
set((state) => ({ random: data }));
},
};
export const initStore = (data) => {
const createStore = () =>
create(
devtools((set, get) => ({
...store,
...data,
}))
);
return createStore;
};
index.js getStaticProps:
export async function getStaticProps(context) {
const res = await fetch("https://jsonplaceholder.typicode.com/users");
const posts = await res.json();
return {
props: {
initZustand: {
posts: posts,
},
},
};
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.