React Native Redux | How To Use Redux In React Native
React Native Redux Example | How To Use Redux In React Native is today’s leading topic. Redux is a standalone state management library, which can be used with any library or framework. If your background is React developer, then you have used the Redux library with React.
Overview of React Native Redux Example
- Step 1: Install React Native on mac.
- Step 2: Add TextBox and Button.
- Step 3: Define the state and input handler.
- Step 4: Create actions, reducers, and components folder.
- Step 5: Create a Reducer function.
- Step 6: Create a Redux store.
- Step 7: Pass the store to the React Native app.
- Step 8: Connect React Native app to the Redux store.
React Native Redux Example Tutorial
The primary use of Redux is that we can use one application state as a global state and interact with the state from any react component is very easy, whether they are siblings or parent-child. Now, let us start the React Native Redux Example Tutorial by installing React Native on Mac first.
We start our project by installing React Native CLI globally on the Mac. You can skip the following command if you have already installed it.
#Step 1: Install React Native.
Type the following command.
npm install -g react-native-cli
Okay, now for creating a new application, type the following command.
react-native init rncreate cd rncreate
Now, after installing, we need to open this application in the two different Simulators.
For testing on iOS simulator, type the following command.
react-native run-ios
If you have configured XCode correctly, then one iOS device will pop up as well as the development server will also start.
To open the project inside the Android Simulator, type the following command.
react-native run-android
Install the redux and react-redux library using the following command.
yarn add redux react-redux # or npm install redux react-redux --save
#Step 2: Add Textbox and Button into the App.js.
Okay, so we will add a text box and button to add places. So let us add the TextInput and Button. Also, we will add the flexbox layout. Write the following code inside the App.js file.
// App.js import React, {Component} from 'react'; import { StyleSheet, View, TextInput, Button } from 'react-native'; export default class App extends Component { placeSubmitHandler = () => { console.log("Submitted"); } render() { return ( <View style={ styles.container }> <View style = { styles.inputContainer }> <TextInput placeholder = "Seach Places" style = { styles.placeInput } ></TextInput> <Button title = 'Add' style = { styles.placeButton } onPress = { this.placeSubmitHandler } /> </View> </View> ); } } const styles = StyleSheet.create({ container: { paddingTop: 30, justifyContent: 'flex-start', alignItems: 'center', }, inputContainer: { flexDirection: 'row', justifyContent: 'space-between', alignItems: 'center', width: '100%' }, placeInput: { width: '70%' }, placeButton: { width: '30%' }, listContainer: { width: '100%' } });
#Step 3: Define the state and input handler.
Okay, now we need a state to manage. So we define the initial state like following.
// App.js state = { placeName: '', places: [] } placeSubmitHandler = () => { console.log("Submitted"); }
#Step 4: Create the following folders inside Root.
Create the following folders.
- actions
- reducers
- components
Inside the actions folder, create one file called types.js. Add the following line inside types.js.
export const ADD_PLACE = 'ADD_PLACE'
The action type is the reducer’s operation type. Based on the action type, the reducer case will be executed, and we modify the state in such a way that it remains pure. So we create a copy of the existing state and return a new state.
Now, create one more file called place.js in the same directory.
// place.js import { ADD_PLACE } from './types'; export const addPlace = placeName => { return { type: ADD_PLACE, payload: placeName } }
The addPlace() function returns an action. Now, based on that action, the reducers function’s case is executed.
But, we need to connect this action to our App.js component somehow. Otherwise, we can not add the data to the Redux store. Also, we need first to create a store. But before, we also need to create a reducer function. So, first, create a reducer, then create a store and then connect the React Native application to the Redux store.
#Step 5: Create a Reducer function.
Inside reducers function, create one file called placeReducer.js. Add the following code inside it.
// placeReducer.js import { ADD_PLACE } from '../actions/types'; const initialState = { placeName: '', places: [] }; const placeReducer = (state = initialState, action) => { switch(action.type) { case ADD_PLACE: return { ...state, places: state.places.concat({ key: Math.random(), value: action.payload }) }; default: return state; } } export default placeReducer;
So, here, we have defined the function called placeReducer that accepts the two arguments.
- state
- action
The first time, it will take the initial state of our application, and then we pass whatever argument; it takes that argument and operates based on the case execution. The second argument is action, which consists of type and payload. The payload is the place name; we have entered inside the text box. So it adds the text box’s value inside places array.
Remeber here; we have returned a new state and not existing state. So we have modified the state in a pure manner and not existing state.
#Step 6: Create a Redux Store.
Inside the root folder, create one file called store.js and add the following code.
// store.js import { createStore, combineReducers } from 'redux'; import placeReducer from './reducers/placeReducer'; const rootReducer = combineReducers({ places: placeReducer }); const configureStore = () => { return createStore(rootReducer); } export default configureStore;
Here, we have created the redux store and passed the reducer to that store. The combineReducer function combines all the different reducers into one and forms the global state. So this is the global state of our whole application.
#Step 7: Pass the Store to the React Native app.
Inside the root folder, you will find one file called index.js, and inside that file, add the following code.
// index.js import { AppRegistry } from 'react-native'; import React from 'react'; import App from './App'; import { name as appName } from './app.json'; import { Provider } from 'react-redux'; import configureStore from './store'; const store = configureStore() const RNRedux = () => ( <Provider store = { store }> <App /> </Provider> ) AppRegistry.registerComponent(appName, () => RNRedux);
It is almost the same as React web application, in which we pass the Provider as a root element and pass the store, and then via react-redux’s connect() function, we can connect the any react component to redux store.
#Step 8: Connect React Native app to Redux store.
Finally, we connect our App.js component to the Redux store. For that, we need the connect() function from the react-redux library.
// App.js import React, { Component } from 'react'; import { StyleSheet, View, TextInput, Button, FlatList } from 'react-native'; import ListItem from './components/ListItem'; import { connect } from 'react-redux'; import { addPlace } from './actions/place'; class App extends Component { state = { placeName: '', places: [] } placeSubmitHandler = () => { if(this.state.placeName.trim() === '') { return; } this.props.add(this.state.placeName); } placeNameChangeHandler = (value) => { this.setState({ placeName: value }); } placesOutput = () => { return ( <FlatList style = { styles.listContainer } data = { this.props.places } keyExtractor={(item, index) => index.toString()} renderItem = { info => ( <ListItem placeName={ info.item.value } /> )} /> ) } render() { return ( <View style={ styles.container }> <View style = { styles.inputContainer }> <TextInput placeholder = "Seach Places" style = { styles.placeInput } value = { this.state.placeName } onChangeText = { this.placeNameChangeHandler } ></TextInput> <Button title = 'Add' style = { styles.placeButton } onPress = { this.placeSubmitHandler } /> </View> <View style = { styles.listContainer }> { this.placesOutput() } </View> </View> ); } } const styles = StyleSheet.create({ container: { paddingTop: 30, justifyContent: 'flex-start', alignItems: 'center', }, inputContainer: { flexDirection: 'row', justifyContent: 'space-between', alignItems: 'center', width: '100%' }, placeInput: { width: '70%' }, placeButton: { width: '30%' }, listContainer: { width: '100%' } }); const mapStateToProps = state => { return { places: state.places.places } } const mapDispatchToProps = dispatch => { return { add: (name) => { dispatch(addPlace(name)) } } } export default connect(mapStateToProps, mapDispatchToProps)(App)
Here, when we click the add button, we get the textbox value and then send it to the action with that value. Now that action returned the object with the action type and payload and based on the type, and the reducer will be executed and add that values inside the store.
Now, if the store’s values are changed, then we need to update the UI based on the new values. That is why the mapStateToProps function is created. So, when the store’s places array gets the new value, render function executed again, and update the UI.
The mapDispatchToProps function helps us to connect our application to the necessary action so that action then further executed by a reducer and change the application state.
Also, inside the components folder, create one file called ListItem.js and add the following code inside it.
// ListItem.js import React from 'react'; import { View, Text, StyleSheet, TouchableOpacity } from 'react-native'; const ListItem = (props) => { return ( <TouchableOpacity> <View style = { styles.listItem }> <Text>{ props.placeName }</Text> </View> </TouchableOpacity> ); } const styles = StyleSheet.create({ listItem: { width: '100%', padding: 10, marginBottom: 10, backgroundColor: '#eee' } }); export default ListItem;
This component receives the properties from the parent component and displays the data in the proper format. Save the file and go to your Simulators, and refresh the screen.
Finally, React Native Redux Example | How To Use Redux In React Native is over. Thanks for taking it.
Recommended Posts
Beginners Guide To Create React Native Application
How To Use React Native ScrollView
How To Connect React Native Application With Laravel API Tutorial
React Native Swipe Components Example
React Native Drawer Navigator Example
Hello,
Some issue in your code am trying to run your code but not able to add placeName to the List..
Can you please give me an error
Hi there,
Could you mind help me to check this error “Could not find “store” in the context of “Connect(App)”. Either wrap the root component in a , or pass a custom React context provider to context consumer to Connect(App) in connect option
It should be written as connect(…)(App)
Where, the “…” contains the functions “mapStateToProps” and “mapDispatchToProps”
mapStateToProps as the name suggests, maps the the store’s variables to the component’s props.
mapDispatchToProps maps the actionable methods (actions) to the component’s props.
Take a look at Section #8 (Connect React Native app to Redux store) of the article to better understand the concept.
Hope this helps!
thanks share,i will try it.
Hello. I’ve followed your tutorial. But I got following error.
Invariant Violation: Could not find “store” in either the context or props of “Connect(App)”. Either wrap the root component in a , or explicitly pass “store” as a prop to “Connect(App)”.
I’ve followed your tutorial. But I get error. How can I solve this?
Invariant Violation: Could not find “store” in either the context or props of “Connect(App)”. Either wrap the root component in a , or explicitly pass “store” as a prop to “Connect(App)”.
Thank for the tutorial but I have an issue regarding index.js for:
AppRegistry.registerComponent(appName, () => RNRedux);
I don’t have that file on my setup 🙁
I have this error: Could not find “store” in either the context or props of “Connect(App)”. Either wrap the root component in a , or explicitly pass “store” as a prop to “Connect(App)”.
Me and 2 people above have problem with this, i don’t think his code work
same error here
same error
Look where you store the store.js file, make sure it is to be found directly after you open your project folder
Hey Krunal, thanks for the tutorial. The code is running fine, but can you make video of this code for better explanation. Why each and every line is coded. That will a great help.
In App Component, you are using local state using this.state instead one should use state.props.places to use common state. In the same way different handlers in App Component are pointing to local store with this.state.
Please update the implementation of App Component to complete the redux integration.
Thank you for tutorial!
Thank you for tutorial
Thank you for the tutorial. A good one.
Very Good Tutorial Boss…. I like It…..,It Works Awesome
where is this root ????/
Root means your main project folder.
That was Awesome…
Thanks Krunal
Having a reducer with state in it… something seems very off about this setup. I’d caution people to learning redux via this article to possible look elsewhere.
I am not sure about this line this.props.add(this.state.placeName)…
Same here…
@Krunal please explain this line.
@Guseyn if you figured it out, please do explain.
Thankxx
I got it…
in app.js in step #8 towards the bottom line:-
const mapDispatchToProps = dispatch => {
return {
add: (name) => {
dispatch(addPlace(name))
}
}
}
this.props.add(this.state.placeName) refers to the method add created in mapDispatchToProps used to dispatch the method addPlace with params this.state.placeName.
Grate Tutorial
I’m facing the following error —
TypeError: (0 , _react.useMemo) is not a function
Thanks krunal..
nice tutorial
Thanks for a concise tutorial.
nice tutorial
Thanks for sharing