Redux Saga handling post action logic - reactjs

I am using React with hooks & Redux saga in my react application.
I have created this sandbox to represent the scenario I am interested in.
So I have a page and a redux store, in that page I perform some sort of action that involves the store, while this action is happening, I want to display a loading indication to the user because this action might take some time to finish. so I add another state to the store that turns on when an action is in progress, if that state is on I show a loading indication to the user.
My question what is your method of handling post action logic, for example: lets say that after the action has finished successfully I want to redirect the user to a different page. how would you approach this with redux saga?

Related

dispatching API actions and loading stage

We know that if a Redux action triggers an API call to a server (whether in Redux middleware or Redux Thunk), it takes time to receive the answer from the server. During this waiting phase, the UI must somehow shows the user that some loading is being done (showing an Spinner for example). In React and React native, a famous trick to handle these common situations is a isLoading boolean flag in the Redux state and of course, a loading action being dispatched. This boolean will be toggled once the answer is ready to be shown, so that I can update the UI.
However, after applying this trick for years, what I've got is an application full of bugs and errors and a super dirty code with a lot of redundant code.
I have checked all the React life cycle hooks to check the order, in which the hooks are called and the process of Redux dispatching. It seems that Redux and React works totally separately. (I know that getDerivedStateFromProps is called once the store has been updated, but it does not solve my problem)
I need a better way to handle these common situations. I don't know if I need to make modification in Redux part of my application, or in the UI, or ...

Best way to integrate React, Redux, Redux-Form, and React-Saga?

I have read everything I can find on how to use react-saga and redux-form together I'm stuck at a crossroads and need some advice.
Here is how I ended up here.
I chose to work with Redux because it makes sense for my app and I don't have any problems there.
Switch from Thunk to Sagas
I started working on my async api calls to populate my app with data. I'm using a lot of data grids and I'm not sure where I'll end up on latency as some of the queries are quite complex.
When I started working on the action creators and methods for doing background polling of data I realized that Sagas were going to be much easier than Thunk.
I made that switch and I'm happy with it. Handling any errors from the api calls is being handled by an action creator that updates redux state container for all of my api calls. Errors are displayed by populating a modal based on those state changes.
Introduciton of Redux-Form
Once I started working on posting form data back to the api things got interesting and I realized I was about to write a lot of code to handle it all through Redux. Redux-form simplified things as it has a state container for everything form related and makes it really easy to setup and validate forms on the client side.
Redux-form handles all of the form state in my configuration until the form is submitted.
I'm using a container component conected to a Redux store I created to hold state of api requests.
The form is a child component of the container that is connected to Redux through redux-form which handles all of it's state.
When the form is submitted I am calling a Redux action which in turn called a saga to post the data.
The result of the saga api call is to either dispatch a success or failure action in Redux. I am passing an object to the api state that contains the status (success/failure), an error object with any errors, and a return object where I can return things like the id's of records just created.
That works well when the error from the api is communication related. Because I'm updating the api state my higher level app components have access to it so I can do things like trigger a modal for errors not specifically related to the form data itself.
But when I started thinking of how I would handle any field errors that could occur if the client side validation was missing some logic I got lost.
In my current setup those errors would be on the api state object. I could put them into a modal but there would be no client side error handling on the form itself.
Redux-form can handle server side validation tied directly back to the form fields but only from a promise and from what I can tell trying to return a promise through action creators would be difficult if not impossible.
I can write a promise in my onSubmit function but I would have to call my saga function directly instead of triggering it through an action. Is that an acceptable pattern?
I guess I could trigger an action from the saga to populate my api state values but it seems backwards.
Basically I would prefer to handle comm errors one way (through my api state container) and form field data errors another way (back throu redux-form and it's error handlers) and I'm not sure which direction to take.
I looked at a module redux-form-saga which makes it possible to return a promise directly back to the form and therefore use the redux-form error handling after the api call but I'm not sure if I would be able to also trigger my api state actions at the same time.
Rather than continuing going down the rabbit hole and maybe over complicating things I thought I would solicit some advice from anyone who has had to deal with something similar.
I'm good with async background calls to populate my data grids but when I have to post data back to the api I want to make sure the user can't take any other actions until they get a response back.
This is the first section of many in this app so I want to create a design pattern that makes sense, is easily reproducible, is reliable, and easy to follow.
Any suggestions?
React-Boilerplate will help you integrate React, redux, redux-saga. On top of that integrating redux-form should be straightforward. React-Boilerplate uses all the current best practices of the community for a production ready app

Using Redux to display a notification in response to a network request

My web application uses React and Redux and UIKit.
It consists of screens A and B.
Screen A contains a button which - upon pressing - will send an asynchronous network request to post some data to a server.
If a user remains on screen A until a response returns from the server, they will receive confirmation about whether or not the request was successful.
The way I have implemented this using React and Redux is by having a component which is responsible for displaying a confirmation banner. This component listens to changes to a state called postStatus in my Redux store. When the user clicks on the button, 3 Redux actions with statuses PENDING, SUCCESS and ERROR are potentially dispatched. After they are dispatched - they are caught by the reducers which change the postStatus state accordingly. This state then gets mapped to my components properties and it is re-rendered to display a relevant banner.
However, if the user does not remain on screen A until a response returns from the server and navigates to screen B instead - I would like a notification to show up so the user is still aware of the status of the request.
My question is, what would be the most sensible way to implement this behaviour?
Here are a couple of things I can think of:
Create a react component that doesn't actually render anything - it just listens to postState and some extra piece of state that represents which screen the user is on. Implement the componentWillReceiveProps react lifecycle method and if the postState is SUCCESS or ERROR and the other state says that the user is on not on screen A - then call UIKit.notify() to show the notification.
Call UIKit.notify() when dispatching the SUCCESS or ERROR action if the user is not on screen A.
Call UIKit.notify() when reducing the state after being dispatched the SUCCESS or ERROR action if the user is not on screen A.
There are most likely a lot of other solutions so I'm keen to hear some.
I know I am late for the answer, but I stumbled upon this myself so here is what I did.
The way I look at it is that the temporary notification is an application side effect.
In my project I am using redux-saga, but you can achieve this using any other side effects library.
The code (using deleting an user as an example):
...
function* deleteUserSuccess(action) {
yield call(message.success, 'Successful deletion!');
}
const watchDeleteUserSuccess = function* () {
yield takeEvery(types.DELETE_USER_SUCCESS, deleteUserSuccess);
}
...
PROS: It is readable and it works.
CONS: The only downside that I see is that you make your sagas know about your UI library. But you can wrap it in a separate function/file/module to abstract the saga from it.

Where should I dispatch actions to fetch my data using React-Native and redux

I want to fetch all the data needed to display the dashboard of my app in react-native. The app is similar to the facebook one
I am using react-native, redux, redux-saga, react-navigation and a REST api.
I have to fetch the post list to display the main page and the notification count for the headerBar. The other tabs pages are mounted at the same time as the main one to allow fluid transition. So I need the current user too for the Account page
Finally, the store is persisted and the app can stay in background mode for a long time. So I need to refresh my data often to be sure to have the last changes.
I have sagas which make the call and launch actions to update the store.
Here the strategies I found :
I can connect each page component and give them a fetchAllPageData() which dispatch a fetch action that I call in componentDidMount
I can connect smaller components to allow them to pull the data they need with the same strategy (ie. fetchUser to the component that display the user in the Account Page, fetchNotificationCount to the component that display the number of notifications ...)
I can use create a redux-middleware which listen for page change and call all fetch data actions.
I am currently using a mix of the first and second solutions but I am not very happy with it :
I don't always know where the data are fetched
The strategies which refresh the data once the component is mounted are a bit "hacky" and random
I often have the to move where the call is done when refactoring
What is the state of the art on this subject? What is your recommendation?
The usual recommendation is to intercept actions that make AJAX requests in the middleware and resolve them there before passing the result through.
This article explains it in more depth.
You can / should do in componentDidMount or componentWillMount.

react redux synchronous call

Building a React application with redux as the flux pattern.
To use an api a token exchange request needs to happen. This has to occur only once when the React application starts. The access_token returned from the token exchange needs to be stored in the redux state and accessible by other api calls.
One approach i tried is by calling a redux action in the App(parent) component, and then all other calls are within children components. New to React i now understand that this is not the right approach as the React components lifecycle events and the actions and reducers called do not follow a synchronous flow, so the redux actions are called asynchronously.
How do i ensure a redux action is called prior to any other redux action that depends on the results of the first redux action? Which middleware would be best suited for ensuring a synchronous approach redux-thunk, redux-look and redux-saga.
If you need a process to run before any other action, you could do it before creating the store, and passing the result in your main reducer function at store creation.
Then, just render the app after the promise or callback of this process is done.
Otherwise, just dispatch this initial action after the store creation, and before app render (with redux-thunk if it is async).
You can use redux-thunk to have a "promise like" behavior when displatching actions. This way you can ensure an action was done before dispatching another one.

Resources