Developing robust web or mobile applications(apps) to handle state internally, as is the norm with React Native components, isn't always ideal. If done improperly, it can quickly become very messy. In situations like these, a library tool like Redux is commonly recommended. In this answer, we'll go through the various steps to manage the state flow in a simple React Native app using the Redux Toolkit.
Redux is a Javascript global state management library designed to act as a central store for managing application states. Redux helps build apps that behave consistently across all environments by providing a system to track all changes made to the state.
Redux Toolkit is Redux's official toolset for developing efficient React-Redux apps. It was designed to simplify the writing of common Redux logic and resolve the usual difficulties of using the core Redux library, such as:
The way these are implemented changes when using Redux Toolkit in place of core Redux.
An action is a simple object that indicates a desire to modify a state in the Redux store. It is required that actions specify a payload and a type attribute that describes what kind of change is to be made to the state. Actions require reducers to be successfully carried out.
A reducer is a pure function that takes two arguments; the current state and an action to return a new state result. Reducers don't modify the original state directly; rather, they make a copy of the state and modify that.
A function that accepts either a synchronous or asynchronous action object and sends it to a reducer for execution.
A collection of reducers and actions that work together to implement a single app feature.
A store is an object that holds the app's entire state tree. Redux can only have a single store in an app.
Obviously, the app we just built is too basic to use a global state manager like Redux. This tutorial was just to introduce Redux Toolkit in the most basic way possible. So we should use Redux as follows:
Note: This answer is not on React Native and will not focus on React Native concepts.
Following is an application to generate random colors.
{ "expo": { "name": "ReduxTutorial", "slug": "ReduxTutorial", "version": "1.0.0", "orientation": "portrait", "icon": "./assets/icon.png", "userInterfaceStyle": "light", "splash": { "image": "./assets/splash.png", "resizeMode": "contain", "backgroundColor": "#ffffff" }, "updates": { "fallbackToCacheTimeout": 0 }, "assetBundlePatterns": [ "**/*" ], "ios": { "supportsTablet": true }, "android": { "adaptiveIcon": { "foregroundImage": "./assets/adaptive-icon.png", "backgroundColor": "#FFFFFF" } }, "web": { "favicon": "./assets/favicon.png" } } }
HomeScreen.js
, we build a simple React-Native application.configureStore
API in place of the createStore
API from core Redux to build a store. The configureStore
also automatically sets up the Redux DevTools Extension and some middleware. The store
holds a single root reducer object for all the state slices in the app.createSlice
in the colorSlice.js
file, we define inside it;name
to identify the slice. initialState
value (just like when using the React useState
hook). reducer
function to determine how the state is to be updated. In the code block, we take the result of the randomRgb function and add it to the original array of colors.Note: We can only write mutating code inside the
createSlice
orcreateReducer
API.
When writing core Redux logic, it is essential to avoid directly mutating the state value. But, with createSlice
available through Redux Toolkit, we can write mutating code in reducers and have it converted into immutable copies.
Notice that we didn't define any action objects in our code. This is because Redux Toolkit allows us to create actions on the fly. Here, we set the case functions defined in our reducer to colorSlice.actions
. Then an action creator is automatically generated using the name of the reducer as the action type. Afterwards, we can import and add the slice to the root reducer of the store.
homeScreen.js
and dispatch an action to our reducer. For this, we'll use the useSelector
hook, which will give us access to our redux state. The useDispatch
hook allows us to dispatch actions. We import useDispatch
and useSelector
from React-Redux. setColor
reducer. Grabbing our current state with state.color.value
, we set it as the data entry in our Flatlist element. Then, by calling useDispatch
as dispatch and passing setColor
in our onPress callback, we can send an action to the appropriate reducer case.Free Resources