This releases fixes a subtle timing bug with connect and useSelector in React Native environments, and adds the ability to pass through non-Redux-store values as a store prop. Fixed Store Subscriptions in React. Npm install react-redux (If you don't use npm, you may grab the latest UMD build from unpkg (either a development or a production build). To use Redux in React Native we will need to install redux which is a standalone library that can be used with any UI layer or framework, We will also need to install react-redux which is the official Redux UI binding library for React. React Redux is maintained by the Redux team, and kept up-to-date with the latest APIs from Redux and React. Designed to work with React's component model. You define how to extract the values your component needs from Redux.
Create a New React App. Create a new project using the Expo CLI tool. Expo init ReduxApp.
Contents
- 2 What is Redux?
- 7 Code to Use Redux in React Native
React Native Redux
Here is an example to use Redux in React Native App. We all know Redux is a state management library which will help you to manage all your state in one place called store. Integration of Redux in React Native is very easy with the help of React Redux. In this example we will see
- Setup of Redux library in your React Native App
- managing of state in a single page
- dispatch actions and handle them in reducers
- use of different state from the Redux store
We request all the readers who are new in React Native and want to learn this concept, please spend some time in understanding props, state and components. Once you have the clear idea of that then you can start with Redux. Although creating a React Native App with Redux is very easy but without understanding the basic concepts you will find it a bit complex.
What is Redux?
Redux is a state management library which helps you to organise your application logic in one place so that your app can work as you expect. Redux makes your application’s code very easy to understand and can you can manage your logic + state regarding when, where, why, and how the state of the application is updated. It is made up of the following key parts:
- actions
- reducers
- store
- dispatch
- selector
Actions and Action Creators
An action is a plain JavaScript object that has a type field and an optional payload. It can also be thought of as an event that describes something that has happened.
Action creators are just functions that create and return action objects.
Reducers
A reducer is also a function that receives the current state and an action object, updates the state if necessary, and returns the new state. A reducer is not allowed to modify the existing state; instead, it copies the existing state and changes the copied values. In other words, the reducer should be a pure function. Here is an example
Store
A store is an object that stores the current state of a Redux application. You create the initial state of the store by passing a reducer to the createStore
function.
Dispatch and Selectors
dispatch() is a Redux store method and is used to update the state by passing an action object.
Selectors are used for reading data from a store.
Here is a flow which can help you to understand it better.
React Native Redux Example Description
In this example, we will create a simple bookmark App, which will have 2 screens one for the listing of bookmarks added and other to list posts. We are not going to store the bookmarks permanently in the App as this is just to understand the concept of Redux.
Whenever User lands on the Bookmark Screen he/she will see all the bookmarks added (Nothing for the first time). Whenever user wants to add bookmarks he/she can click on the add button from the bookmark screen and can see the list of post to add any post in bookmark. Once user click on any post it will disappear from the post list and will be added in the bookmark, user can see the total number of the bookmarks added in the header. When user press back button he/she will see the updated bookmark list, which can be sorted ascending/descending on the basis of post id.
For the post listing we have postData state in out store and for the bookmark we have bookmarkItems. Whenever a user lands on the post screen we will dispatch getPostsList function as an action which will be a async function for which we have used react-thunk middleware. Once we get the response of the fetch we will dispatch an action with payload which will update our postData state which will hep us to render the post list.
On click of any post we will dispatch addToBookmark action with payload which will add the clicked record in bookmarkItems and will remove that record from postData. As mentioned above user can also sort the bookmarked list which can be done using sortBookMarkList action.
I hope you understood what we are going to do so let’s start creating the React Native App with Redux.
To Make a React Native App
Getting started with React Native will help you to know more about the way you can make a React Native project. We are going to use react-native init to make our React Native App. Assuming that you have node installed, you can use npm to install the react-native-cli
command line utility. Open the terminal and go to the workspace and run
Run the following commands to create a new React Native project
If you want to start a new project with a specific React Native version, you can use the --version argument:
This will make a project structure with an index file named App.js in your project directory.
Installation of Dependencies
To install any dependency open the terminal and jump into the project using
To use Redux in React Native we will need to install redux which is a standalone library that can be used with any UI layer or framework, We will also need to install react-redux which is the official Redux UI binding library for React.
For this example we are calling an API which is an async action and for that we will need to add redux -thunk to support the same.
We are using React Navigation for this example so we also need to install the dependencies for the navigation
Other supporting libraries for Navigation
For Stack Navigator
This command will copy all the dependencies into your node_module directory. –save is optional, it is just to update the dependency in your package.json file.
Project Directory/File Structure
To start with this example you need to create the following directory/file structure. Project will have a src directory with all our code, src directory will have two more directories components and utils. All these directory will have following files for complete example.
You can see
- App.js contains main navigation
- src/BookmarkScreen.js, landing page which will have all the bookmarks
- src/PostList.js, contains the list of posts which user can add in bookmark
- src/components/HeaderCountLabel.js, Counter label in PostList header to show number of bookmark added
- src/components/HeaderSortLabel.js, to sort added bookmarks
- src/utils/actions.js, having all the action function definitions
- src/utils/reducers.js, having all the state management on the basis of actions
Code to Use Redux in React Native
App.js
src/BookmarkScreen.js
src/PostList.js
src/components/HeaderCountLabel.js
src/components/HeaderSortLabel.js
src/utils/actions.js
src/utils/reducers.js
React Redux Tutorial
To Run the React Native App
Open the terminal again and jump into your project using.
To run the project on an Android Virtual Device or on real debugging device
or on the iOS Simulator by running (macOS only)
Output Screenshots
This is how you can use Redux in React Native App. Redux is a valuable tool, but it’s only useful when used in the right way. Some of the situations where Redux might be helpful include code that is being worked on by many people or applications that contain large amounts of application state.
If you have any doubts or you want to share something about the topic you can comment below or contact us here. There will be more posts coming soon. Stay tuned!
Hope you liked it. 🙂
You have finally decided that you are going to use React for your application and you are all pumped up to start development until that fateful moment when you realize that you need data from a different component & the complexity of passing that data through props is making your code & your life HELL.
Here comes Redux to your rescue!!
In simple terms, Redux acts like a container to store the state of your javascript application which is accessible across all your components.
But why would you need such a thing?
Imagine this, you have your item listing application & for each item a user can mark it as favourite which would not only update your list view but also a total favourites list in your header.
You might be thinking that’s pretty easy, I can just pass the favourite list as props and update the element. But what if that component is deeply nested in your application which makes passing props through parent child component extremely ugly & complex or worse where you can’t pass a prop to the component–for instance Route Components like this:
You need a better, scalable solution.
Redux helps you to handle such scenarios gracefully.
Great, but how can you use this with your React application?
Redux in itself is not bound to any UI framework, you can use it with Vue, React, Ember and a lot more. Having said that, it is only possible for a UI framework to use Redux through a UI binding library which ties Redux to your UI framework.
React Redux is the official Redux UI binding library for React
Before we see how we can implement react-redux for an application, we need to understand few terminologies
1) The Store
2) Action Creators
3) Reducers
The Store
Store is a centralised place where all your application state sits. Consider it as your bank which holds all your cash. It looks something like this in Redux Dev Tools.
Action creators
Let’s take our previous analogy of Redux Store acting as a bank, now you would definitely want to either withdraw or deposit money right? And what would you do? You would raise a request to do so. Action creators acts as those requests. They emit actions which encapsulates the changes you want to make in the Store.
Ok moving on..
Reducers
Now once you have raised a request to deposit or withdraw something, you have to then submit that request to your bank manager (P.S-we are overlooking online banking here for a second :P). The bank manager knows exactly how to process that request, and if everything looks good, he/she will deposit or withdraw the amount requested, hand it over to you and update the details in your account to reflect the new changes.
This is what Reducers do for you in Redux. They take whatever action you pass, make a copy of the existing state, apply all your updates to the state & finally publish the updated state changes to the store.
React Redux Application Flow
- To begin with, we have our React Component which is encapsulated by connect() from react-redux which gives the component access to the store using mapStateToProps() as well as allows the component to dispatch actions using action creators.
- So, if we want to update something in the store, we will call action creators from our React component.
- These action creators will then dispatch specific actions.
- Our Reducers will interpret these actions and apply the requested changes to the store.
- Finally, we can access these updated changes of the store in our component through mapStateToProps().
Let’s play around with react-redux
Now as we know these building blocks a little better, it’s time to see how they come together in our application. I am going to keep this as simple as possible so you can understand the flow properly. We are going to create a simple list with 2 items either of which you can add to your favourite’s by clicking Favourite button and when you click again, the item will be removed from the favourite’s list.
Install React Redux
Pre-requisite: You can setup a sample app using create-react-app. If at any point you feel stuck, you can refer to the source-code here.
Step 1. Install react-redux
Step 2. Setting up store
Once you have installed all the above dependencies in your React app, the next step is to setup Redux Store in your application.
Add the following lines in your main index.js file from where you render your using ReactDOM.
Don’t worry if you are not clear what each of these lines do yet, I’ll explain you shortly 🙂
Now let’s understand what exactly are we doing in the above code.
- The createStore() from redux helps us to create an instance of our store.
- We cannot directly pass this store to our
<App/>
, the only way to pass store instance to our entire application is through<Provider/>
component by react-redux. We pass a store attribute to this component whose value is our store instance. - Do you recall the store snapshot I showed earlier, that is possible only through Redux Dev Tools which enables developers in real time to view the State, Actions and a lot more fired across your application. It’s extremely useful for debugging, though a good idea would be to only enable it during development.
- Next, we have imported something called rootReducer from reducers. rootReducers have all our reducers combined. We will be creating this file shortly.
- Once we have imported everything, it’s time to instantiate our store. Our createStore() is taking rootReducers as first argument, our initial state object as second argument and lastly our composeWithDevTools() as third argument.
- Finally, we are passing the store to component which encapsulates our component.
Step 3. Creating Action Creators
For our above example, we would be needing 2 action creators
- To add item in favourites.
- To remove item from favourites.
It’s a good practice to keep all your action creators in one directory. So, let’s create a directory named actions/ inside src/
Next, create an index.js file with actions/ directory.
Within that we will write our 2 action creators.
- Our action creators (markFavourite() & removeFavourite()) are just plain functions which returns an object describing what the action is.
- The type key is mandatory as it states the action type in plain string. To avoid name collision the general practise is to define types as constants and place them in separate file like we did above.
- The name key you see is just payload–any additional data which you need to update in store. You can add your own custom payload in whatever key you want.
Step 4. Creating Reducer
Creating action creator is just half the battle, we need something that understands those actions and updates our store. That is where Reducers come into picture.
Generally a real world application has multiple reducers, hence for clarity & better maintenance we should place all our reducers in a separate directory under src/ as reducers/
Next, let’s create our itemActions.js reducer file which will interpret our MARK_FAVOURITE & REMOVE_FAVOURITE actions.
- itemActions is the name of our reducer as well as the key under which we would be able to access our favourites(Remember in the second step we passed initial state object which has itemActions key).
Note: The 1st argument of any reducer is the state which is initialised with default state for that reducer & the 2nd argument is the action which the reducer is going to interpret.- Within itemActions() exists a switch case which identifies what code should be executed for the give action type.
- Now, in order to update state the most important thing to keep in mind is to not directly mutate the state. What I mean by that is, always create a copy of state object either using Object.assign() or spread operator like above and then update the object based on some condition.
- For our MARK_FAVOURITE action, we are adding new item name to our favourites & for our REMOVE_FAVOURITE action we are filtering out the given item name.
Step 5. Combining Reducers
As real world application generally have more than one reducer, its necessary to pass all of them while we initialize the store. combineReducers() from redux precisely does that for you.
Let’s see how it’s done!!
First create an index.js file within your reducers/ directory
Remember the rootReducers import which we did while creating store in Step 2, this is where it’s imported from.
So far we have covered the creation part of react-redux application, now it’s time to see how we can invoke our action creators from our component & access this state from store.
Step 5: Invoking Action Creators & Accessing State
In order for our component to have access to the Store & invoke action creators we would need some sort of binding function. connect() from react-redux does exactly that.
Let’s see how we can invoke this. Please refer to the complete code here
Redux React Native
- connect()
- takes 2 arguments:
- mapStateToProps() which takes 2 arguments state(our redux store) & ownProps(props received from parent component)
- The 2nd argument is an object stating our action creators.
Note – Don’t make a mistake of directly importing and using action creators functions. You need to pass them to a connect() which makes a dispatch object available to our action creator using which an action is dispatched to the reducer which in turn updates the store.
- Both the arguments are optional. If you wish to only access Store state in a particular component just pass mapStateToProps and keep 2nd argument null & vice versa.
If you were able to be with me so far, Kudos to you.
Conclusion
Though mastering Redux has a learning curve, taking the first step without getting overwhelmed is very crucial. I hope this post helps you create your first tangible react-redux application 🙂
Resources:
Demo Application Source Code
https://react-redux.js.org/introduction/quick-start
https://redux.js.org/introduction/getting-started
Mosh’s Course on Mastering React
Hope you enjoyed reading this post as much as I did writing this. If you liked this post, please share it and you can also follow me on twitter @arwa18793