Redux Tookit, How to dispatch action in a non component function? - reactjs

I have a global toast, which I am opening using redux slice. I need to open the toast for error message when call from api fails in api-slice of rtk-query.
I have seen the answer, using store.dispatch method, but this causes dependency cycle. Is there a way to do this?

Yeah, you should always avoid directly importing the store into other application files.
Ideally, none of the rest of your code would ever need to refer to store directly.
Depending on where in the RTKQ setup you need to trigger this toast, you may have access to dispatch as part of the lifecycle function arguments.
In the worst case, you can use our fallback recommendation to inject the store into the necessary files from the app setup logic.

Related

having trouble fixing dependency cycle in redux

One of my redux actions requires access to a class that manages api requests.
However in my api requests class, I wrote a method that requires importing the data store. I then began getting the following error:
Cannot access 'WEBPACK_DEFAULT_EXPORT' before initialization
I looked up the error and mentions It is due to a dep cycle, it seems that this pattern is causing the importing of an uninitialized data store.
summery: Since my redux slice imports the api class and the api class depends on the redux store how can i restructure my code to fix this pattern?
We specifically advise Redux users that you should never import the store directly into other files, except the main app entry point file, because of this sort of import cycle problem.
The best approach here would be to restructure your logic so that this class file doesn't need to use the store at all.
As a secondary fallback, you can expose a setter from that module that saves the store reference, and call that setter from the entry point on startup.

How can I access the Redux store from a function?

I am creating a React components library that exports a TypeScript function that another app can use. In that function, I need to retrieve some information from the app's store. How can I do this?
I cannot import the store and do store.getState() since I wouldn't know where the app's store is. Is there a way I can use connect() to do it?
If it's possible to design your function as a custom React hook, then you can use useSelector() inside it.
If it's not feasible, than shaping arguments to expect store been passed in - is a way. Especially if you are going to target older versions of react-redux, without useSelector

Creating Redux actions for API calls that don't modify the state directly

We are developing a React application using Redux to manage the state. In general, Redux serves us well, but in one part of the application, we are using WebSockets to update our app state to allow all the connected users to have the most recent version of the data.
It looks like this: https://i.stack.imgur.com/uNAsk.png
In a regular Redux application, we would have 3 actions: ACTION_LOADING, ACTION_SUCCESS and ACTION_FAILURE to handle HTTP requests. In this case, the state is updating automatically after receiving new data from the WebSocket.
Is it correct to have a Redux action (thunk) to post this data to the server even if it does not modify the state, or is it better to call the service without using Redux in these cases?
In case we create actions, what pattern would you recommend?
Thank you.
I would recommend wrapping it in a thunk for a couple of reasons:
There's nothing fatal about initiating an action that doesn't end up mutating state (for whatever reason).
Even if you aren't doing anything in the case of a successful POST (since all the action will come later via a message from the server), you still might need to dispatch an actions in case the POST fails for some reason.
It allows your components to use one consistent mechanism (action dispatch) rather than sometimes one way and sometimes another.

Using react hooks in conjunction with redux-saga (or any other middleware)

This question was already asked here before, however I didn't find yet any proper answer, just wonder if I missed anything or if indeed this is currently not possible.
Specifically, there are 2 main differences between hooks & redux-saga (or any other middleware):
in redux-saga I can trigger code execution on action dispatch, while in hooks I can trigger code execution only on state change. These 2 are not always equivalent
hooks must exist in context of component, however some "background" logic (such as initialization, location detection, etc), is not related to a specific component. In redux-saga I have the flexibility to define it in "global scope", while in hooks I must attach it to some "random" component (probably App or any other high level component).
So, is it possible to "bridge" somehow between these 2 approaches, or should I simply pick the most appropriate technique for each specific case ?
They are different tools to solve different problems. Hooks work internally to a functional component's state and lifecycle. Redux works internally to an entire react app's state and lifecycle. Sagas help wrangle asynchronous effects like external data fetches.
Generally speaking you want to limit the scope of variables and logic as much as possible. If a specific piece of "state" is only relevant to a single component, then keep it in component state. But if several components or the application itself needs it, then store it in app state. Same applies for asynchronous calls. If a single external call is used by only one component, keep it there, but if multiple components can make the same external async calls, then let the sagas handle them.
You are free to use as much, or as little, as is necessary of either in each component to solve your problem.
In Redux-saga you can execute code only on action dispatch. Hooks are more generic, for example with the useReducer hook you can trigger code on action dispatch, with useEffect you can trigger code on mount/update/unmount etc.
Redux-saga also exist in context of a component, or more precisely, whole Redux exists in a (usually top-level) store provider component and Redux-saga is only one of its middlewares. So basically if you have some global app logic and put a hook for it in your App component, it is not some random component, it is the right place to put the logic to.
I've also recently found a simple library https://www.npmjs.com/package/use-saga-reducer that introduces sagas to React's useReducer. (I'm still not sure it is a good idea - just because you can doesn't mean you should, for me hooks async functions are usually enough, but it is at least interesting)

View-specific server-calls in redux application

We have a React / Redux application that usually fetches data via the "normal" way - a view calls a dispatcher, the dispatcher calls our server and dispatches an action with the result, which is then put into the state via a reducer.
Now, I'm creating a view that needs to call the server to get a custom URL based on a few properties. It's not global state at all - since it's just this view that's going to be using it.
It doesn't feel right to call the server from the view directly, but it doesn't feel right to put this data in the global state either.
What is the best practice in these kinds of situations?
You could bypass the "biased standard" here and create an action/lib file to do the fetching for you, and then let the result of that promise (or callback) be the input to the dispatch you will continue with.
From the question you ask, I assume you are going to do this for more than one component? If so, I think that the mentioned approach will suffice.
Further, if you are only doing this for one component, it could be enough to just put that logic in the component, or in a parent container (HoC).

Resources