With the mutuality of JavaScript, several frameworks have emerged. React is one of those frameworks that have come up with an effective way to manipulate the virtual DOM. Using React, every user interface section is viewed and composed as a single independent component that has a state. Any changes that occur in the section are determined by the state which the component is always listening to. Changes in the state results to react updating the virtual DOM tree. The uniqueness in react is seen when the changes occur in the virtual DOM. Immediately, react takes that current DOM and compares it with the virtual DOM after which it will only update only those objects that have changed on the virtual DOM. This brings about a huge performance increase to the table compared to using vanilla JavaScript. The center of all this is the “ ”. So if each component has a state, say we need to access one component state in another component? Or manipulate data in one state and still see the changes on another component? These are the questions that Redux comes to answer with the idea of having a store that has a state or states which operates on a global level. State These states are accessible by all components on the application in that changes or manipulation reflects throughout the application. See, simple. So do I use a React Redux throughout my entire application or I can mix it up with React state? In this article, we will demonstrate how to use both React Redux and React state in the same application. Using React state To set up a react state, we initializing local state by assigning an object to on the inside a class. this.state constructor { (props) { (props); .state = { : , : [], : , }; } class ItemCocktails extends Component constructor super this isLoading false itemCocktail id null Once that is done, we deploy the function of react. The function is involved immediately when the component is mounted which is good given that we want the asynchronous operation to be triggered on mount followed by a dom tree manipulation. componentDidMount() componentDidMount() { .setState({ : }); { id } = .props.match.params; axios({ : , : , : { : , : , : , : , }, : { : id, }, }) .then( { .setState({ : , : response.data.drinks, id, }); }) .catch( { error; }); } this isLoading true // eslint-disable-next-line react/destructuring-assignment const this method 'GET' url 'https://the-cocktail-db.p.rapidapi.com/lookup.php' headers 'content-type' 'application/octet-stream' 'x-rapidapi-host' 'the-cocktail-db.p.rapidapi.com' 'x-rapidapi-key' 'add key here' useQueryString true params i => response this isLoading false itemCocktail => error throw Each and every time a is called to modify the state, it as well triggers a render which will happen before the browser updates the screen. This way, the user cant see the intermediate state. In our case, we employ a condition which acts as a safeguard in a case where the asynchronous operation has not finished executing after which it is set to false. Once the promise has been executed the response is captured by the and used to set a new state with the needed data. setState() isLoading . then To improve the user experience, we use condition rendering to display awaiting asynchronous operation. render() { { isLoading, itemCocktail, id } = .state; loadData; (isLoading === ) { loadData = ( <div className="alert alert-info" role="alert"> Loading data in a moment! </div> <Loading /> ); } ( isLoading === && itemCocktail !== && itemCocktail.length > ) { data = itemCocktail.map( item); loadData = <div> <div className="alert alert-danger" role="alert"> Something went wrong! Navigate back to home page </div> <Loading /> </div> <div className="container">{loadData}</div> const this let if true < > div </ > div else if false null 0 const => item ; } else { loadData = ( < = = /> ItemCocktailCard itemData {data[0]} key {id} ); } return ; } } Using React Redux State Asynchronous operation using react-redux requires a extension that allows simple asynchronous updates by dispatching an action thus interacting with the store. One of the most popular middleware extensions is which is now part of the . In this article, we will not dive deep into redux-thunk(see the documentation to get started). middleware Redux Thunk react toolkit Redux Thunk allows you to write action creators that return a function instead of an action. The thunk can be used to delay the dispatch of an action, or to dispatch only if a certain condition is met. middleware The first step in configuring redux is to have actions. Actions have to have a type which will be the condition which has to be met for the reducer to execute. fetchCocktailByCategory = ({ : FETCH_COCKTAILS, cocktails, }); const => cocktails type The above function is an action that sets the type and adds the cocktails payload. With that set, next, we need to have the asynchronous function which will provide the needed data payload. fetchAllCocktailByCategory = dispatch => { allCategories = [ , , , , , , , , , , , ]; allCategories.map( axios({ : , : , : { : , : , : , : , }, : { : category, }, }) .then( dispatch( fetchCocktailByCategory([category, response.data.drinks]), )) .catch( { error; })); }; export const => () const 'Ordinary Drink' 'Cocktail' 'Milk / Float / Shake' 'Other/Unknown' 'Cocoa' 'Shot' 'Coffee / Tea' 'Homemade Liqueur' 'Punch / Party Drink' 'Beer' 'Soft Drink / Soda' return => category method 'GET' url 'https://the-cocktail-db.p.rapidapi.com/filter.php' headers 'content-type' 'application/octet-stream' 'x-rapidapi-host' 'the-cocktail-db.p.rapidapi.com' 'x-rapidapi-key' 'add key here' useQueryString true params c => response => error throw The above is a high order function as it returns another function in our case . Once the execution has completed and the promises resolved, the response is passed and dispatched invoking the action function and passing the payload. fetchAllCocktailByCategory() dispatch fetchCocktailByCategory() The reducer function is always listening for the type to be provided after which it set the payload as a new state. { FETCH_COCKTAILS } ; cocktailReducer = { (action.type) { FETCH_COCKTAILS: [...state, action.cocktails]; : state; } }; import from '../actions/types' const ( ) => state = [], action switch case return default return The only thing remaining is at this point is to call the reducer at the top level. In most cases an application has more than one reducer, thus it is important to combine them using from redux and call it as one root reducer. combineReducers { combineReducers } ; cocktailReducer ; categoryReducer ; FilterByCategoryReducer ; rootReducer = combineReducers({ : cocktailReducer, : categoryReducer, : FilterByCategoryReducer, }); import from 'redux' import from './Cocktails' import from './Category' import from './FilterByCategory' const cocktails categories filter The is invoked at the index and passed as a parameter at the redux function that creates the store. rootReducer createstore { createStore, applyMiddleware } ; thunk ; rootReducer ; { fetchAllCocktailByCategory } ; store = createStore(rootReducer, applyMiddleware(thunk)); store.dispatch(fetchAllCocktailByCategory()); import from 'redux' import from 'redux-thunk' import from './reducers/index' import from './utils/utils' const Using a reducer is the recommended approach when dealing with a state in a large application. In a large application, the reducer can even be nested where one reducer calls another to provide the next state. The critical issue is for the developer to analyze their system requirements and operation so as to decide to use the react state or use redux. To get the complete code at github image by Academind, Sep 19, 2016