The ecosystem has become huge since Facebook made the API public. More so, great libraries have been built in the declarative style adopted by React. React However, real life applications require making AJAX requests to servers. And this can pose a great challenge while using React. You need to know what library to use for your AJAX processes. It’s good to know that there are different ways to handle AJAX with React. This is one of the beauties of React as a — . VIEW library flexibility How to make AJAX request with React Within React component. Delegate Relay. Delegate Redux. 1. Within React Component This is the simplest and the most common approach for AJAX requests. Here, the AJAX request is issued directly in the lifecycle method of your component. Things can get messed up this way as your application grows. componentDidMount A request to Github API to get user details looks like this: Basic implementation of AJAX within React component Let’s test it out… Basic implementation of AJAX within React 2. Delegate Relay allows you to declare the data requirements for your components with GraphQL. And relay makes them available via props. Relay Relay is elegant for building large applications — but it has some overhead. This ranges from learning relay and GraphQL to setting up GraphQL servers. A sample relay flow could look thus: https://facebook.github.io/react/blog/2015/03/19/building-the-facebook-news-feed-with-relay.html 3. Delegate Redux is built off of for managing React application’s state. With Redux, you move your application data and AJAX processes away from your components. Redux Flux architecture Redux workflow example From the diagram, you can see how the application state and asynchronous processes are moved to the store. is an object that holds the complete state of your app. Note that in Redux, all application states are stored as a single object. The only way to change its state is by . With this implementation, you maintain a single source of truth across your application. Store dispatching actions are just pure functions that take the previous state and an action and then return the new state. It does not mutate state; it makes a copy of the previous state, transforms it, and returns a new state to the store. The store then updates the view with the new state if there are changes. Reducers , given the same arguments, should calculate the next state and return it. No surprises. No side effects. No API calls. No mutations. Reducers are synchronous and passive, thus not the ideal place for async actions. Reducers (previousState, action) => newState How then should you handle operations with side effects? Redux async libraries comes to rescue: Redux-promise Redux-thunk Redux-saga They are Redux middlewares for handling async tasks and side effects in your React/Redux application. uses Flux standard actions and promises to bring clear conventions to async calls. It’s the least popular among the three. It is a middleware function that receives a promise and dispatches the resolved value of the promise. It basically returns a promise to the caller so that it can wait for the operation to finish before continuing. Redux-promise allows an action creator to return a function instead of an action object. This way, the action creator becomes a . Redux-thunk thunk A is a function that is created, often automatically, to assist a call to another function (e.g API endpoint). A thunk wraps an asynchronous operation in a function. thunk When an action creator returns a function, that function will get executed by the Redux Thunk middleware. This function doesn’t need to be pure; thus, it is allowed to have side effects, including executing asynchronous API calls or router transition. The function can also dispatch actions. To enable Redux Thunk, we use . applyMiddleware() If Redux Thunk middleware is enabled, any time you attempt to dispatch a function instead of an action object, the middleware will call that function with dispatch method as the first argument. Check as , the creator of Redux, and Redux-thunk gives a detailed explanation of use cases. here Dan Abramov We can dispatch both plain object actions and other thunks, which lets us compose the asynchronous actions in a single flow. Basic AJAX request with redux-thunk middleware Redux-thunk is easy to learn with relatively small API — Just ten lines of code. But can be difficult to test. Let’s test it out … Implementing AJAX with redux-thunk Still curious, see another example. Async action is a Redux middleware that eliminates the complexity of asynchronous processes within your React/Redux application. It leverages the power of to make async tasks easy to test, write, and reason. Redux-saga ES6 generators Redux-saga manages async request and side effects in a more terse way than other middlewares for this. It reduces complexities in such requests by making blocks to just simple instructions. More so, it makes your code declarative, more testable and readable. Whereas you could use R and R together, Sagas are just the thing to cure your complex workflow pains. callbacks, promises, try/catch edux-thunk edux-saga When your store needs to handle complex async operations, consider using Redux-saga. It handles asynchronous operations as simple instructions. Redux-saga manages async tasks elegantly, keeping your reducer pure. A) Define Sagas Saga Sagas are generator functions. It uses the ES6 generator. Check out article on Kyle Simpson’s Basics of ES6 generator. Generators are functions that can be paused and resumed. Because of the way generators work, Redux-saga is able to make complex asynchronous workflows look synchronous. We have two sagas to complete this operation: and . Sagas are identified by * in front of the function. watchRequest loadUserDetails Redux-saga API exposes some methods which we need to complete our task: is an effect creator that runs a function with optional parameters. It suspends the generator as the result returned is a promise. The generator is resumed when the promise is resolved or rejected. call is an effect creator for making non-blocking calls on a function. fork cancels any current operation and return the result of the latest action that matches its pattern. takeLatest returns the result of all actions that matches its pattern. takeEvery simply puts/dispatches actions to specified channel put (an object used to send and receive messages). Check out the for more. documentation . Back to our code watches for LOAD_USER_REQUEST actions to be dispatched. takeLatest It then makes a non-blocking call to with the returned action object. In this case, the action type and username. loadUserDetails runs the function with the payload(i.e username) and resolves the value assigned as call gitHubApi user. Now, dispatches LOAD_USER_SUCCESS with the user value back to the store. put Finally, if the operation fails, it’s good practice to dispatch failure action, which in our case is LOAD_USER_FAILURE. B) Mount Sagas on the store Mount Sagas to the store To make the store’s state and functions available to the React component, provides: React-redux function — connects a React component to a Redux store. connect — a higher order component to make the store available to all container components in the application without passing it explicitly. Provider component 3) Connect React component to Redux store Connect React connect React component to Redux store let’s test it out … Sample implementation of AJAX with React and Redux-saga. Wrap up AJAX operations in your React application are better handled with Redux async libraries. When using Redux, Separation of concern is key. More so, if your React/redux application requires making async operations, use Redux-thunk or Redux-saga to handle it with agility and elegance. Making async requests within your reducers is an anti-pattern and should be avoided. don’t put AJAX in your React components. Check out the source code on . Github Many thanks to , , and for taking out time to go through the draft. Emmanuel Isaac AbdulQudus Abiodun Shuaib Oluwafemi Sule This article was originally published on . You can check it out . Note: Codementor here In case I missed out on anything, drop your feedback, comments and questions in the comment section. If you find this article useful, recommend it to others by hitting 💚 and also by sharing on social media.