Manage your States Easily and Keep it Clean with Redux-Toolkit in React Native

İlter Köse
5 min readJun 27, 2021

I’m Ilter from Istanbul, Turkey. I’m Mobile Developer & Senior (4rd Year) EE engineering student who has a passion for software development.

Introduction

Hi Folks! In this article, I am going to talk about 2021’s rising star, Redux Toolkit. Redux Toolkit’s popularity has been increasing every month since 2021. So, It is obvious that It will shape all the Redux structures in the future.

What is the Redux Toolkit?

Redux Toolkit is a package that makes the handling Redux logic easier and cleaner in your apps. According to official docs of Redux Toolkit, It answers couple questions about topics such as

  • Hard to configure Redux stores
  • Package dependency of Redux
  • Redux has complicated code block between Navigations, Components,Pages.

that mostly asked by Junior — New Grad Developers or Software Developers who started to built React applications. Because of these topics, Redux has became hard to learn completely and build architecture with it.

So, If you are a brand new Redux user or you have legacy, complicated Redux code that you want to make it clearer, Redux Toolkit can help you to make them happen.

Getting our hands dirty

First things first, you must have React Native in your computer. After that lets create a React Native project.

npx react-native init MediumReduxToolkit --template react-native-template-typescript

You might ask why I used TypeScript? It depends on your choice. However, TypeScript allows us to create Enums and Types. So, I suggest you to use TypeScript with Redux Toolkit.

Afterwards, we have to install redux packages.

npm install @reduxjs/toolkit react-redux
npm install --save-dev @types/react-redux

Now we have installed our packages then we have to move on to the building the app. You can build on iOS or Android with the commands below.

// iOS build phase
cd ios/
npx pod-install
cd .. // Go back to project source.
npx react-native run-ios
// Android build phase
npx react-native run-android

Nice we are good to go! Now you can open your IDE or Code Editor.

Lets Create State Slice

Before creating our Slice file, I want to mention the folder structure that I used for Redux Toolkit.

In your project’s src file, open redux folder and inside of that folder we will create all the redux related stuff.

I will explain this file one by one but for now we will focus on name.slice.ts

What is Slice File & createSlice?

In redux, we were using createActions, createReducers manually but now, createSlice handles all the process. In slice file we are creating a slice function with createSlice which contains every major thing of redux state.

So createSlice contains:

  • name: a parameter that will be the prefix for all of your action types
  • initialState: the initial state for our reducer
  • reducers: it's an object where we have action objects and functions which we decide how to update the state and as a result, returns the new state.

The most beneficial part of createSlice is clean folder structure. We can put anything related to redux in just one file. Reducers, Actions, Initial States even Redux Thunk middleware - I will mention in the next article - too.

import {createSlice} from '@reduxjs/toolkit';export enum NameEnum {
NO_NAME = 'NO NAME',
FIRST = 'john',
SECOND = 'doe',
LAST = 'ilter',
}
export const defaultName = NameEnum.NO_NAME;const NameSlice = createSlice({
name: 'name',
initialState: {
nameState: defaultName as NameEnum,
},
reducers: {
setName: (state, action: {payload: NameEnum}) => {
state.nameState = action.payload;
},
},
});
export const {setName} = NameSlice.actions;export default NameSlice.reducer;

As you can see, with these configurations we don’t have to write our actions separately anymore

We can export all the actions, the reducer. Also, you can export selector on this file too, however I suggest you to create a new folder called selectors and create your selectors there.

import {createSelector} from 'reselect';
import {RootState} from '../store';
export const getName = createSelector(
(state: RootState) => state,
state => state.name,
);

With this selector, we can get state from all around the app.

Creating the Store

We have created our State slice, now we have to create our store. The major point here is configureStore, configureStore helps us to create main reducer that can store and combine all the reducers on the app.

import {configureStore} from '@reduxjs/toolkit';
import nameReducer from './name.slice';
export const store = configureStore({
reducer: {
name: nameReducer,
},
});
export type AppDispatch = typeof store.dispatch;
export type RootState = ReturnType<typeof store.getState>;

Afterwards, we have to wrap our app with Provider

const App = () => {
return (
<Provider store={store}>
<Mainpage />
</Provider>
);
};

Creating Custom Hook

I suggest you to use and create custom hooks. You may ask why, the answer is simple. You might need declare types for AppDispatch when your app has different SDKs or packages.

import {useDispatch} from 'react-redux';
import {AppDispatch} from './store';
export const useAppDispatch = () => useDispatch<AppDispatch>();

Let’s Test our Code!

We have declared our state and wrapped the App. Now we will build a screen to test our Slice. In order to do that, we need to code screen with events to change global state which is stored in Redux Toolkit.

import React from 'react';
import {StyleSheet, Text, View, TouchableOpacity} from 'react-native';
import {useSelector} from 'react-redux';
import {useAppDispatch} from '../redux/hooks';
import {setName, NameEnum} from '../redux/name.slice';
import {getName} from '../redux/selectors/getName';
const Mainpage = () => {
const {FIRST, SECOND, NO_NAME, LAST} = NameEnum;
const {nameState} = useSelector(getName);
const dispatch = useAppDispatch();
return (
<View style={styles.container}>
<Text style={{color: 'red', fontSize: 28}}>{nameState}</Text>
<TouchableOpacity
onPress={() => {
dispatch(setName(FIRST));
}}>
<Text>Set First Name</Text>
</TouchableOpacity>
<TouchableOpacity
onPress={() => {
dispatch(setName(SECOND));
}}>
<Text>Set Second Name</Text>
</TouchableOpacity>
<TouchableOpacity
onPress={() => {
dispatch(setName(LAST));
}}>
<Text>Set Last Name</Text>
</TouchableOpacity>
</View>
);
};
export default Mainpage;const styles = StyleSheet.create({
container: {flex: 1, justifyContent: 'space-evenly', alignItems: 'center'},
});

As you can see, I have created a simple page to test our experiment. I want to mention that the page is connected the Redux store with useSelector and useAppDispatch hooks. We do not need not only connect() function but also mapDispatchToProps objects on the below. With the power of Redux Toolkit we can connect our screens easily and keep our code clean.

End of the Line

To sum up, We have created a little slice to handle global state from all over the app. As you can see we never set any local hooks to handle states. We never utilized useState hook. From now on, you can use Redux Toolkit in your next projects. I am sure that you will really love Redux Toolkit after a few tries.

For any questions you can email me: ilter.kose@ozu.edu.tr

--

--