I am using this typescript code to set the UI loading status animation in react hooks:
React.useEffect(() => {
setUserDocList(projList.projects);
setProjFolders(projList.folders);
setProjLoading(false);
}, [projList]);
and listening the projList like this:
const { projList, folderProjList } = useSelector((state: AppState) => state.proj);
When projList
changes, will trigger the useEffect. Now I facing the issue that the projList
will trigger before the http response change the global state. Is it possible only capture the http response change events? Only set the loading status to false with the http response change. The http request look like this:
export function getProjectList(req: QueryProjReq) {
const params = new URLSearchParams();
for (const [key, value] of Object.entries(req)) {
params.append(key, value);
}
const config: AxiosRequestConfig = {
method: 'get',
url: '/tex/project/list',
params: params
};
const actionTypeString: string = ProjectActionType[ProjectActionType.GET_PROJ_LIST];
return XHRClient.requestWithActionType(config, actionTypeString, store);
}
the http request will get the projects from server side and dispath the result to reducer. I want to trigger the UI loading to false after recive the http response project list. But now the useEffect will trigger when init the component, so the loading animation will never render in UI because everytime initial the component the loading status will set to false. I only want to set the loading status to false after the projects response.
2
Answers
To ensure that the loading status is set to false only after the HTTP response has successfully updated the projList in your global state, you need to differentiate between the initial state of projList and its state after receiving the HTTP response. This can be achieved by tracking the loading state more explicitly in relation to your HTTP request.
Here’s a strategy you can employ:
Define a loading state in your global store: If not already defined, maintain a loading state related to project list requests in your global store. This state should be set to true when the HTTP request starts and set to false when the request completes (both in success and failure cases).
Trigger loading state changes with your HTTP request: Adjust your action creators to dispatch actions that toggle this loading state at the start and end of your HTTP requests.
Listen to the loading state in your component: Instead of (or in addition to) listening to changes in projList, also listen to changes in the loading state you’ve defined in the global store. Use this state to control the UI loading indicator.
Here’s how you can implement these steps:
Step 1 & 2: Adjusting the Global Store and HTTP Request Handling
Adjust your action creator to manage the loading state:
Step 3: Listen to the Loading State in Your Component
In your component, listen to the loading state:
export default MyComponent;
Make sure your reducer handles actions related to setting the loading state (SET_PROJ_LOADING in the example) by updating isLoadingProjList in the global state.
By following these steps, you ensure that your component’s UI loading indicator accurately reflects the loading status of your HTTP request, only disappearing once the projList has been successfully updated in response to the HTTP request.
Try this NPM package.
https://www.npmjs.com/package/@codewagon/active-stream
It works well for us. We Subscribe to the events on the component
and fire the event from the Services once there is a response.