Install React Redux
Redux Toolkit#
Redux Toolkit includes the Redux core, as well as other key packages we feel are essential for building Redux applications (such as Redux Thunk and Reselect).
It's available as a package on NPM for use with a module bundler or in a Node application:
It's also available as a UMD build, which can be loaded from the dist
folder on unpkg. The UMD builds make Redux Toolkit available as a window.RTK
global variable.
Redux Core#
To install the stable version:
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. 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 npm install -save-dev redux-devtools Note that unlike Redux itself, many packages in the Redux ecosystem don't provide UMD builds, so. Create a New React App. Create a new project using the Expo CLI tool. Expo init ReduxApp.
Install React Redux Devtools
If you're not, you can access these files on unpkg, download them, or point your package manager to them.
Most commonly, people consume Redux as a collection of CommonJS modules. These modules are what you get when you import redux
in a Webpack, Browserify, or a Node environment. If you like to live on the edge and use Rollup, we support that as well.
If you don't use a module bundler, it's also fine. The redux
npm package includes precompiled production and development UMD builds in the dist
folder. They can be used directly without a bundler and are thus compatible with many popular JavaScript module loaders and environments. For example, you can drop a UMD build as a <script>
tag on the page, or tell Bower to install it. The UMD builds make Redux available as a window.Redux
global variable.
The Redux source code is written in ES2015 but we precompile both CommonJS and UMD builds to ES5 so they work in any modern browser. You don't need to use Babel or a module bundler to get started with Redux.
Complementary Packages#
Most likely, you'll also need the React bindings and the developer tools.
Note that unlike Redux itself, many packages in the Redux ecosystem don't provide UMD builds, so we recommend using CommonJS module bundlers like Webpack and Browserify for the most comfortable development experience.
Create a React Redux App#
The recommended way to start new apps with React and Redux is by using the official Redux+JS template for Create React App, which takes advantage of Redux Toolkit and React Redux's integration with React components.
Are you looking for something that helps you write mobile applications in React Native that behave consistently, run in different environments, and test easily? There is a solution, and you just found it! You have certainly come across the fact that when your application gets bigger and more complex, it’s hard to manage states and pass data from one component to another component (or child components). There's exactly where redux can help you: it gives global access to state or data, which can be used in any component without depending on other components.
The article is a beginner's comprehensive on how to use redux and redux toolkit in a React Native application. This guide assumes that you know the basics of React Native but, if this is new to you as well, we've got you covered with our React Native tutorial. We are also using an Android emulator in this tutorial, something that allows you to simulate an Android device on your computer so you can test your application on a variety of devices and Android API levels without needing to have each physical device. Notice that this emulator provides almost all of the capabilities of a real Android device. Finally, to help you learn the basics of redux, we provide, along the way, code examples of a simple counter application. It will look something like this:
Here is the code of our SimpleCounter component:
Right now, this code is static, and we have not declared any state inside the component. Feel free to follow along with the code examples as we integrate redux in our react native app. Our React Native tutorial (link above) will show you how to set up a React Native enviorment, after that, make sure you install the redux and react-redux libraries. To do that simply use the command:
If you are using npm 5.0.0 or superior type this instead:
What is redux and why use it ?
Redux is a javascript library made to help you manage the state of your application. It does that by providing the developer with a centralized place called the store, where the state is saved and modified through actions and reducers. This centralized place enables you to share the state between multiple screens and to know exactly where and how the state is being modified. This is particularly useful in growing applications that are too large for the developers to have full knowledge of the data flows and, consequently, become bug prome.
How to use redux
As said above, redux uses a combination of actions, reducers and the store to manage the application state. To understand and learn redux, you need to know how these abstractions works. Let's start!
The State
Very lightly, the application state is all the information that the application uses and/or modifies. Having a centralized state and a predictable way of modifying it can enable applications to be coherent with the information that they show to the users. This is particularly useful for large single page applications.
Actions and reducers
Actions and reducers together modify the state. Precisely, actions determine what is being modified and where. Reducers specify how it is being modified. By analyzing the layout at the beginning of the blog post, we will need three actions: INCREMENT, DECREMENT, and CHANGE_BY_AMOUNT. Actions are objects with a type and a payload attribute. The type is the action's identifier, and the payload is all the information that the reducer will need to modify the state. The first two actions will only decrement or increment the counter amount by 1, so we only need to define two objects with the attribute type, and the reducer will handle the rest. The third action must have a payload to specify how much we want to increment or decrement the counter. Declare your actions in a separate file called Actions:
As you can see, it is pretty simple. Next, we define the initial state. This is done in another file along side with the reducer:
We set the initial state to have an object named counter with the attribute amount, starting at 0. You can also see that the initial state is a constant and not a variable, which appears to make no sense, but we will explain it to you later. Next, we build the reducer, which is a function that receives the current state and the action - as arguments - to produce the new state of the application. Here it is:
We must not mutate the state in the reducer. Why? In fact, the reducer should not modify the state object directly. Instead, it should create a new object, which will be the new state. React’s rendering engine compares the previous state object with the latest state object. If you modify the state directly, React does not know what has changed, and it will have a flawed notion of the application state. You can start reading about this here. This is why, in the beginning, we declared the initial state as a constant and not as a variable, as we pretend the initial state object never to be altered.
The Store
The next step is to create the store. The store is the object where the state is saved. It is common practice to create the store and export it in a separate file. Check it below:
We create the store using the createStore() method from redux, which receives as argument the reducer function defined earlier. With the store, we can invoke actions with the dispatch method (will be shown later in this guide) to modify the state. Now we make the store available by passing it to the Provider component that engulfs our SimpleCounter component. What the Provider component does is provide access to the store in the SimpleCounter component and all the components inside it. The Provider component is imported from the react-redux library, which is the official binding library for react/react native and redux.See below how to do it:
Connect your react components
Next, we want to connect our components to the redux store. We can do this by using the connect method from react-redux library in our SimpleCounter component file, like so:
We need to pass two arguments to the connect method: the component we want to connect (SimpleCounter) and a function that maps the application state to our component props. Note that we only have access to the state object in the mapStateToProps function because we engulfed the SimpleCounter component with the Provider component. The connect method is merging the object returned from mapStateToProps with the props of the SimpleCounter component to access the state.counter.amount value via this.props.amount. The dispatch method also becomes available through props, and we can now import our actions and dispatch them inside the SimpleCounter component. Here’s the SimpleCounter component updated code:
React Native state persistance
So now we have a centerlized store were the state is saved and modified in a predictable way through actions and reducers, but you might have noticed that the counter value returns to zero every time you refresh or exit the app, this is because right now the state is not being persisted and every time you open the application the reducer is defining the counter value to be zero (the initial state).
State persistance is important if you need to maintain certain information even when the user closes the application, like login tokens or some configuration settings. You can achieve state persistance in a React Native app by using the redux-persist library. Redux persist saves the redux store into a local persistent storage and retrieves it every time the app is re-openned or refreshed. We are using an Android emulator, but redux-persist also works with IOS. Let's start by installing redux persist:
After that, modify the Store.js file, like so:
First import both persistStore and persistReducer methods from redux-persist library. Pass the reducer to the persistReducer method along side the persistConfig object to create a persistedReducer. In the persistConfig object declare that you are going to use the AsyncStorage to persist the redux store which is an uncrypted key-value storage from React Native. Finally, call the persistStore method to ensure that our store is persisted. If you have a bigger project, you might not need to persist the entire state, in that case, you can use a 'Whitelist' and 'Blacklist' methodology in the persistConfig object to choose which reducers you want to persist, click here if you want to know more. Last, in the App.js file import the persistedStore from Store.js and engulf the SimpleCounter with the PersistGate component to make sure that the app's UI is not rendered until the persisted state is retrieved and saved into the redux store.
Redux toolkit
We have to mention the Redux toolkit, a library written by the redux developers to help create more efficient redux logic. Utilizing this library's functions will result in your code being more compact and simpler to read. Here is an introduction to some of those functions:
createAction()
Redux toolkit introduced us with a new way of creating an action. It works like this:
The createAction method receives the action type as an argument and returns an action creator function. We can then call this function and pass the payload as an argument to create the action object. You can also access the action type with the toString() method, like so, incrementAction.toString(). This method makes it so that we no longer need to declare the action types as constants reducing the boilerplate code significantly.
createReducer()
This is another method of the redux toolkit that aims to simplify our code. The method allows us to write reducers with the lookup table notation, enabling us to write a much cleaner code. The objects returned from the createAction() method can be used directly as the table keys. Following with the previous reducer logic, we have:
In addition to this, createReducer() also uses Immer to write reducers with simpler mutating logic. Immer translates all mutating operations into equivalent copy operations. So now, we can write our reducer like this:
Much simpler don't you think ?
configureStore()
The configureStore() function wraps around the createStore() method and creates the store setting up some standard configurations. Also, the method receives a configuration object instead of a group of functions so, when using it, you must pass the reducer inside an object associated to the reducer attribute. Like this:
Store configuration is a matter that we did not include in this blog post, but we felt that it was still important to mention so, if you want, feel free to explore it yourself. One more thing, if you want to integrate redux-persist and redux-toolkit in the same project you might have came across the error 'A non-serializable value was detected in an action' this is because redux-toolkit's configureStore() incorporates a serializable check on actions and redux-persist needs to pass a function inside them. One way you can solve this is importing getDefaultMiddleware from redux-toolkit and disabling the serializable check on redux-persist actions types. Like so:
You can find the discussion and the solution for this problem in this forum.
React And Redux
In short
How To Install React-redux Cmd
There it is. The result should be a simple but functional counter app. We hope you learned how redux's abstractions work together and familiarized yourself with the dataflows that they create, so it becomes easier for you to start applying redux to your app. Additionally, redux is an independent library, so the logic you learned here would be the same if you wanted to integrate redux in a web application that uses react. Wish you the best of luck programming!