React Native’s New Architecture—powered by Fabric, TurboModules, and Codegen—enhances performance and improves the developer experience. But when it comes to global state management, Redux is still a go-to solution for many developers.
In this guide, we’ll walk through setting up Redux in a React Native project using a clean, scalable, and future-proof structure, fully compatible with the New Architecture.
📦 Step 0: Install Redux Packages
Let’s start by installing the essential Redux packages:
Using npm:
npm install @reduxjs/toolkit react-redux
Or using yarn:
yarn add @reduxjs/toolkit react-redux
@reduxjs/toolkit
provides a modern Redux setup with less boilerplate.
react-redux
connects your React Native components to the Redux store.
🗂 Folder Structure
We’ll organize Redux inside the src/
folder like this:
/src
├── /store
│ ├── configureStore.js
│ └── rootReducer.js
├── /services
│ └── /app
│ ├── reducer.js
│ └── actions.js (optional)
└── App.js
⚙️ Step 1: Configure the Store
src/store/configureStore.js
import { configureStore } from '@reduxjs/toolkit';
import rootReducer from './rootReducer';
const store = configureStore({
reducer: rootReducer,
devTools: true,
middleware: getDefaultMiddleware =>
getDefaultMiddleware({
serializableCheck: false, // Avoid warnings for non-serializable values like navigation
}),
});
export default store;
🧠 Step 2: Create Root Reducer
src/store/rootReducer.js
import { combineReducers } from '@reduxjs/toolkit';
import { appReducer } from '../services/app/reducer';
const combinedReducer = combineReducers({
app: appReducer,
});
const rootReducer = (state, action) => {
if (action.type === 'USER_LOGOUT') {
state = undefined;
}
return combinedReducer(state, action);
};
export default rootReducer;
This handles app-wide state reset on logout.
Step 3: Create Actions, Constants, and Reducers
Next, create folders and files for actions, constants, and reducers.
Create the following directory structure inside the store
folder:
store/
Home/
action/
index.js
constant/
index.js
reducer/
index.js
Actions
Define your actions in store/Home/action/index.js
.
// store/Home/action/index.js
import { TEST_NAME } from '../constant';
export const addValue = (text) => ({
type: TEST_NAME,
payload: text,
});
Constants
Define your action types in store/Home/constant/index.js
.
// store/Home/constant/index.js
export const TEST_NAME = 'TEST_NAME';
Reducers
Handle the state changes in store/Home/reducer/index.js
.
// store/Home/reducer/index.js
import { TEST_NAME } from '../constant';
const initialState = {
value: '',
};
const inputValueReducer = (state = initialState, action) => {
switch (action.type) {
case TEST_NAME:
return {
...state,
value: action.payload,
};
default:
return state;
}
};
export default inputValueReducer;
Step 4: Integrate Redux with React Native Components
Now, let's integrate Redux with a React Native component.
Home Screen
Create or modify a screen component to dispatch actions and read state from the Redux store.
// screens/Home.js
import React, { useState } from 'react';
import { Button, StyleSheet, Text, TextInput, View } from 'react-native';
import { useDispatch, useSelector } from 'react-redux';
import { TEST_NAME } from '../../store/Home/constant';
const Home = ({ navigation }) => {
const [value, setValue] = useState('');
const text = useSelector((state) => state.inputValueReducer.value);
const dispatch = useDispatch();
return (
<View style={styles.container}>
<Text onPress={() => navigation.navigate('Profile')}>Home</Text>
<TextInput value={value} onChangeText={(text) => setValue(text)} style={styles.input} />
<Button
title='Send'
onPress={() => {
dispatch({ type: TEST_NAME, payload: value });
}}
/>
<Text>{text}</Text>
</View>
);
};
export default Home;
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
},
input: {
borderColor: 'gray',
borderWidth: 1,
padding: 10,
marginBottom: 10,
width: '80%',
},
});
Step 5: Wrap Your Application with the Provider
Finally, wrap your application with the Provider component from react-redux to make the Redux store available to your entire app.
// App.js
import React from 'react';
import { Provider } from 'react-redux';
import store from './store/configStore';
import Home from './screens/Home';
const App = () => {
return (
<Provider store={store}>
<Home />
</Provider>
);
};
export default App;
Conclusion
By following these steps, you've successfully integrated Redux and Redux-Thunk into your React Native application. This setup provides a scalable architecture for managing state and handling asynchronous operations, making your application more robust and maintainable.
Top comments (1)
Nice guide! I see we’re still inviting Redux to every state party, huh? At least with all these folders, we won’t lose it in the coatroom. Any tips for not drowning in reducers as the app grows?