0

I am new to redux so apologies if it's a stupid question. I have a react application and I am adding redux store to it. I am using thunk middleware to execute async code to get/save data from the backend.

I have this below in index.js:

store.dispatch(loadInitialState());

loadInitialState() calls backend service and loads the initial data and dispatches an action to load initial state:

 dispatch({
  type: LOAD_INITIAL_STATE,
  payload: initData,
 });

Now, in case things didn't go well I dispatch a set error action like this:

dispatch({ type: SET_ERROR_MESSAGE, payload: errorMessage });

and the reducer has got this:

case actions.SET_ERROR_MESSAGE:
      return {
        ...state,
        error: action.payload,
      };
case actions.RESET_ERROR_MESSAGE:
      return {
        ...state,
        error: null,
      };

I have a component called <DisplayError /> that I have included in App.js at the top where on every page of the application this component will be first one to render and it uses useSelector(state => state.error) to find if there and an error to display it.

The problem: If I have an error on a route/page and if I navigate away from that route the error message stays there because that component it common at the top of all pages. The only way I see to solve this is to do dispatch({ type: RESET_ERROR_MESSAGE, payload: null }); everywhere in the application to make sure that error message doesn't appear where it's not supposed to.

What is the way to reset error that set in redux state?

Toseef Zafar
  • 1,601
  • 4
  • 28
  • 46
  • A few things: The redux store has no relation to the routing. That's the whole point of the Redux storage, so you have data everywhere. If you have a component watching for the error message to be present in the store in all pages, either that component has to handle the route where to show which errors OR indeed you will have to call reset after the error message is displayed (or when navigating away). Last thing: There's no stupid question. Stupid is to have questions and not ask ;) – gr33nTHumB Dec 11 '22 at 00:09
  • 1
    Thanks @gr33nTHumB! :) understood about redux has nothing to do with routing. I can take one of the approaches you mentioned in your comment. Now, is there a "right way" here to handle errors or these are common approaches? – Toseef Zafar Dec 12 '22 at 10:40
  • 1
    Well, the "right" way in my opinion is with callbacks, when talking about queries. This: https://react-query-v3.tanstack.com/guides/queries sets a pretty good standard IMO. Think about it this way: Errors are local instances of messages you need to show to the user. So you should show them, but not necessarily store them in your data store. So you use a callback, do the alerting in the way you want to and that's it. – gr33nTHumB Dec 14 '22 at 01:42
  • `useQuery` is actually very nice, thanks for sharing it. so I assume the good practice is to keep all API calls within the component (e.g. using useQuery) and then dispatch relevant redux actions? One case that I need to understand is there is a component that shows data from the db on the home page and in `App.js` I dispatch a thunk function that loads that data, I am wondering if something goes wrong while loading data for the initial state then I can probably keep an error in the store in that case? because I wont be able to tell in that component that something has gone wrong. – Toseef Zafar Dec 14 '22 at 13:05
  • "the good practice is to keep all API calls within the component (e.g. using useQuery) and then dispatch relevant redux actions?" in my opinion, yes. – gr33nTHumB Jan 21 '23 at 05:37
  • "One case that I need to understand is there is a component that shows data from the db on the home page and in App.js I dispatch a thu..." short answer is: you should not be doing that in `App.js` but rather in a component specific to that data, where you would manage it's life-cycle, including errors. This applies even if it's something that will be visible throughout the app. Still good hygiene to keep things isolated IMO. – gr33nTHumB Jan 21 '23 at 05:38
  • And what I do is separate all the API stuff into it's own folder, like `src/api` or `src/queries` for instance, so it's reusable. DRY :) – gr33nTHumB Jan 21 '23 at 05:41
  • Added a compilation of the above as an answer ;) – gr33nTHumB Jan 21 '23 at 05:45

1 Answers1

1

A few things...

The redux store has no relation to the routing. That's the whole point of the Redux storage, so you have data everywhere. If you have a component watching for the error message to be present in the store in all pages, either that component has to handle the route where to show which errors OR indeed you will have to call reset after the error message is displayed (or when navigating away).

So what's the right way to do it?

Well, the "right" way in my opinion is with callbacks, when talking about queries. This: react-query-v3.tanstack.com/guides/queries sets a pretty good standard IMO. Think about it this way: Errors are local instances of messages you need to show to the user. So you should show them, but not necessarily store them in your data store. So you use a callback, do the alerting in the way you want to and that's it.

"Ok, so the good practice is to keep all API calls within the component and then dispatch relevant redux actions?"

In my opinion, yes. Isolation and reusability are always in my mind at least.

"One case that I need to understand is there is a component that shows data from the db on the home page and in App.js I dispatch a thu..."

Short answer is: you should not be doing that in App.js but rather in a component specific to that data, where you would manage it's life-cycle, including errors.
This applies even if it's something that will be visible throughout the app.
Good hygiene to keep things isolated IMO.

gr33nTHumB
  • 368
  • 2
  • 9