When building complex React Native applications, managing state efficiently becomes crucial. Redux, a popular state management library, along with Redux-Thunk for handling asynchronous actions, provides a powerful solution. In this guide, we'll walk you through setting up Redux and Redux-Thunk in a React Native project.
Prerequisites
Ensure you have the following packages installed in your React Native project:
"react-redux": "^9.1.2",
"redux": "^5.0.1",
"redux-thunk": "^3.1.0"
Step 1: Set Up the Store
Create a store folder in the root directory of your project. Inside this folder, create two files: configStore.js
and rootReducer.js
.
configStore.js
This file configures the Redux store and applies middleware.
// store/configStore.js
import { createStore, applyMiddleware, compose } from 'redux';
import { thunk } from 'redux-thunk';
import rootReducer from './rootReducer';
import Reactotron from './ReactotronConfig'; // Optional, if you are using Reactotron for debugging
const middleWare = applyMiddleware(thunk);
const store = createStore(
rootReducer,
compose(middleWare, Reactotron.createEnhancer()) // Remove Reactotron if not using
);
export default store;
rootReducer.js
This file combines all the reducers.
// store/rootReducer.js
import { combineReducers } from 'redux';
import inputValueReducer from './Home/reducer';
const appReducer = combineReducers({
inputValueReducer,
});
const rootReducer = (state, action) => {
if (action.type === 'USER_LOGOUT') {
state = undefined;
}
return appReducer(state, action);
};
export default rootReducer;
Step 2: 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 3: 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 4: 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.