I'm coming from redux + redux-saga and class component, everything went well when using componentDidMount in class component. Dispatching action to fetch api works well without duplicate request.
I've been learning functional component for a while, and decided to use Zustand to replace my redux-saga to handle my state management process. I've able to set state A from state B in reducer just by calling the action creators and the state get updated.
First of all, here's my react functional component code so far:
HomeContainer
import { useEffect } from "react";
import { appStore } from "../App/store";
export default function HomeContainer(props: any): any {
const getCarouselData = appStore((state: any) => state.getCarousels);
const carousels = appStore((state: any) => state.carousels);
useEffect(() => {
if (carousels.length === 0) {
getCarouselData();
}
}, [carousels, getCarouselData]);
console.log("carousels", carousels);
return <p>Home Container</p>;
}
Loading Slice
const loadingSlice = (set: any, get: any) => ({
loading: false,
setLoading: (isLoading: boolean) => {
set((state: any) => ({ ...state, loading: isLoading }));
},
});
export default loadingSlice;
App Store
import create from "zustand";
import homeSlice from "../Home/store";
import loadingSlice from "../Layout/state";
export const appStore = create((set: any, get: any) => ({
...loadingSlice(set, get),
...homeSlice(set, get),
}));
Coming to Zustand, it seems like the behaviour is different than Redux. I'm trying to update the boolean value of loading indicator with this code below:
import create, { useStore } from "zustand";
import axios from "axios";
import { appStore } from "../App/store";
const homeSlice = (set: any, get: any) => ({
carousels: [],
getCarousels: () => {
appStore.getState().setLoading(true);
axios
.get("api-endpoint")
.then((res) => {
set((state: any) => ({
...state,
carousels: res.data,
}));
})
.catch((err) => {
console.log(err);
});
appStore.getState().setLoading(true);
},
});
export default homeSlice;
The state is changing, the dialog is showing, but the component keeps re-render until maximum update depth exceeded. I have no idea why is this happening. How can I update state from method inside a state without re-rendering the component?
Any help will be much appreciated. Thank you.