DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Please enter at least three characters to search
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Zones

Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks

Last call! Secure your stack and shape the future! Help dev teams across the globe navigate their software supply chain security challenges.

Modernize your data layer. Learn how to design cloud-native database architectures to meet the evolving demands of AI and GenAI workloads.

Releasing software shouldn't be stressful or risky. Learn how to leverage progressive delivery techniques to ensure safer deployments.

Avoid machine learning mistakes and boost model performance! Discover key ML patterns, anti-patterns, data strategies, and more.

Related

  • Navigation in a React Native Web Application
  • How to Build Scalable Mobile Apps With React Native: A Step-by-Step Guide
  • Mastering React App Configuration With Webpack
  • How to Build a React Native Chat App for Android

Trending

  • Transforming AI-Driven Data Analytics with DeepSeek: A New Era of Intelligent Insights
  • Why High-Performance AI/ML Is Essential in Modern Cybersecurity
  • Docker Model Runner: Streamlining AI Deployment for Developers
  • A Modern Stack for Building Scalable Systems
  1. DZone
  2. Coding
  3. JavaScript
  4. Ultimate Guide for Using Redux With React Native

Ultimate Guide for Using Redux With React Native

By 
krissanawatt kaewsanmunag user avatar
krissanawatt kaewsanmunag
·
Jul. 17, 20 · Tutorial
Likes (3)
Comment
Save
Tweet
Share
13.5K Views

Join the DZone community and get the full member experience.

Join For Free

Redux is a popular React and React Native state management library, meant to be used in complex React and React Native apps where sharing state between multi-level components can get extremely difficult to manage. In this article we are going to learn how to use Redux with React Hooks by building a real React Native app.

This is how the final app will look like:

final app

React Hooks provide us  the ability to use functional components in React or React Native apps. Their ability to provide support to manage a component’s state and handle side-effects offers an alternative to class components.

In this tutorial, let us take a look at some of the hooks provided by the react-redux library that provides a way to avoid writing boilerplate code when using the connect() High Order Component (if you’re not familiar with connect(), don’t worry, that doesn’t matter that much anymore).

1. Create a New React Native App

To shorten the amount of time spent on configuring a new React Native app, I am going to use expo-cli with a blank template to generate a new app. You can also follow this complete tutorial using react-native-cli to generate a new app.

Shell
xxxxxxxxxx
1
 
1
expo init projectname


After the project has been generated, please navigate inside the directory and install the following dependencies.

Shell
xxxxxxxxxx
1
 
1
yarn add redux react-redux @react-navigation/native @react-navigation/stack


I am going to use Stack Navigator from the react-navigation library for two different screens in this demo app.

If you are using expo-cli, run the following command to install required dependencies for the navigator to work.

Shell
xxxxxxxxxx
1
 
1
expo install react-native-gesture-handler react-native-reanimated react-native-screens react-native-safe-area-context @react-native-community/masked-view


If you are using a project generated with react-native-cli it is recommended to follow the instructions from here to install the required dependencies and any other configuration with native OS platforms.

2. Create Two Mock Screens

In this section, let us create two screens that the app is going to use to display a list of items and allow the user to add to each item. Create a new directory called src/screens and then create two new files:

  • ListScreen.js
  • ModalScreen.js

Each of these screen files is going to have some random data to display until the stack navigator is set up.

Here is the code snippet for ListScreen.js:

JavaScript
xxxxxxxxxx
1
44
 
1
import React from 'react'
2
import { StyleSheet, Text, View } from 'react-native'
3
4
function ListScreen() {
5
  return (
6
    <View style={styles.container}>
7
      <Text>List Screen</Text>
8
    </View>
9
  )
10
}
11
12
const styles = StyleSheet.create({
13
  container: {
14
    flex: 1,
15
    backgroundColor: '#fff',
16
    alignItems: 'center',
17
    justifyContent: 'center'
18
  }
19
})
20
21
export default ListScreen
22
Here is the code snippet for ModalScreen.js:
23
24
import React from 'react'
25
import { StyleSheet, Text, View } from 'react-native'
26
27
function ModalScreen() {
28
  return (
29
    <View style={styles.container}>
30
      <Text>Modal Screen</Text>
31
    </View>
32
  )
33
}
34
35
const styles = StyleSheet.create({
36
  container: {
37
    flex: 1,
38
    backgroundColor: '#fff',
39
    alignItems: 'center',
40
    justifyContent: 'center'
41
  }
42
})
43
44
export default ModalScreen


3. Set Up a Stack Navigator

A Stack Navigator allows the app to transit between different or multiple screens and manages the navigation history. Create a new file called AppNavigator.js inside the src/navigation directory. This file is going to contain all the configurations required to set up a Stack Navigator.

With the recent release of react-navigation version 5, the way to configure a stack navigator has changed. The major highlight of these new changes is the component-based configuration. Some of the other highlights, which the team of maintainers enumerated in a blog post, are that the navigation patterns are now more component-based, common use cases can now be handled with pre-defined Hooks, the new architecture allowing you to configure and update a screen from within the component itself. There were a few other changes as well.

JavaScript
xxxxxxxxxx
1
 
1
import * as React from 'react'
2
import { NavigationContainer } from '@react-navigation/native'
3
import { createStackNavigator } from '@react-navigation/stack'
4
5
import ListScreen from '../screens/ListScreen'
6
import ModalScreen from '../screens/ModalScreen'


The NavigationContainer is a component provided by the react-navigation library that manages the navigation tree. It contains the navigation state and wraps all the navigator’s structure.

The createStackNavigator is a function that implements a stack navigation pattern. This function returns two React components: Screen and Navigator, that are going to allow us to configure each component screen.

JavaScript
xxxxxxxxxx
1
14
 
1
const Stack = createStackNavigator()
2
3
function MainStackNavigator() {
4
  return (
5
    <NavigationContainer>
6
      <Stack.Navigator>
7
        <Stack.Screen name='List' component={ListScreen} />
8
        <Stack.Screen name='Modal' component={ModalScreen} />
9
      </Stack.Navigator>
10
    </NavigationContainer>
11
  )
12
}
13
14
export default MainStackNavigator


Open the App.js file and import the MainStackNavigator in the root of the app as shown below:

JavaScript
xxxxxxxxxx
1
 
1
import React from 'react'
2
import MainStackNavigator from './src/navigation/AppNavigator'
3
4
export default function App() {
5
  return <MainStackNavigator />
6
}


Now, go the terminal window and execute the command expo start. In the simulator or the real device you are running the Expo client, you are going to notice similar results as shown below:

Initial screen with no customization

The first screen in the Stack Navigator is ListScreen which is shown as above.

4. Create an Overlay Modal With Transparent Background

The modal can be easily configured with a stack navigator with an overlay of transparent background on the screen it is displayed. In the current app, since the ListScreen is going to be the first screen and will display a list of items, the ModalScreen is going to be a dialog that appears by clicking a button from the ListScreen. This dialog, when opened, adds a transparent layer on the screen behind it. The previous screen will be visible underneath this dialog.

This can be done by configuring screenOptions on a Stack Navigator. The react-navigation library provides a way to enable the overlay with a property called cardOverlayEnabled.

Modify AppNavigator.js file as following:

JavaScript
xxxxxxxxxx
1
31
 
1
function MainStackNavigator() {
2
  return (
3
    <NavigationContainer>
4
      <Stack.Navigator
5
        mode='modal'
6
        headerMode='none'
7
        screenOptions={{
8
          cardStyle: { backgroundColor: 'transparent' },
9
          cardOverlayEnabled: true,
10
          cardStyleInterpolator: ({ current: { progress } }) => ({
11
            cardStyle: {
12
              opacity: progress.interpolate({
13
                inputRange: [0, 0.5, 0.9, 1],
14
                outputRange: [0, 0.25, 0.7, 1]
15
              })
16
            },
17
            overlayStyle: {
18
              opacity: progress.interpolate({
19
                inputRange: [0, 1],
20
                outputRange: [0, 0.5],
21
                extrapolate: 'clamp'
22
              })
23
            }
24
          })
25
        }}>
26
        <Stack.Screen name='List' component={ListScreen} />
27
        <Stack.Screen name='Modal' component={ModalScreen} />
28
      </Stack.Navigator>
29
    </NavigationContainer>
30
  )
31
}


Nothing will happen as of now. You still have to configure the styles of both the screens and add a way for the modal dialog to open from the ListScreen.

5. Navigate to the Modal Screen

To navigate to the modal screen, let’s add a floating action button with an icon to the ListScreen.js screen component.

This button is going to be touchable and on a single touch is going to navigate to the ModalScreen. The navigation is going to be handled by the navigation prop that can be passed as an argument to the functional component ListScreen. This is only possible because the ListScreen is part of the Stack navigator.

Any screen in a React Native app that utilizes a react-navigation library is a route or a part of a navigation pattern that has access to navigation prop.

Modify the ListScreen.js file as below:

JavaScript
xxxxxxxxxx
1
47
 
1
import React from 'react'
2
import {
3
  StyleSheet,
4
  StatusBar,
5
  Text,
6
  View,
7
  TouchableOpacity
8
} from 'react-native'
9
import { Ionicons } from '@expo/vector-icons'
10
11
function ListScreen({ navigation }) {
12
  return (
13
    <View style={styles.container}>
14
      <View style={styles.fabContainer}>
15
        <TouchableOpacity
16
          onPress={() => navigation.navigate('Modal')}
17
          style={styles.fabButton}>
18
          <Ionicons name='ios-add' color='#fff' size={70} />
19
        </TouchableOpacity>
20
      </View>
21
    </View>
22
  )
23
}
24
25
const styles = StyleSheet.create({
26
  container: {
27
    flex: 1,
28
    backgroundColor: 'blue'
29
  },
30
  fabContainer: {
31
    justifyContent: 'flex-end',
32
    flexDirection: 'row',
33
    position: 'absolute',
34
    right: 10,
35
    bottom: 20
36
  },
37
  fabButton: {
38
    backgroundColor: 'blue',
39
    borderRadius: 35,
40
    width: 70,
41
    height: 70,
42
    alignItems: 'center',
43
    justifyContent: 'center'
44
  }
45
})
46
47
export default ListScreen


Go back to the simulator device, and you are going to notice the changes. The first thing to notice is the action button floating at the bottom right corner.

Added modal popup button

On pressing this button, a full-screen modal will open.

Full-screen modal

6. Add a Custom Modal With a Transparent Background

In this section, let’s change the behavior of how the modal appears on the ListScreen right now and how we want it to be. As an overlay, we also want it to take the only 1/3rd of the current screen.

This modal is going to have an input field in the future to let the user add items to the list. However, for now, it is going to display a text and a close button.

The close button is going to dismiss the modal when the user wants to go back to the List screen without taking any other action. The close button is going to be placed using position: absolute property and is going to use navigation.goBack() pre-defined method to go back to the List screen.

Here is the complete code for the modal screen at this point. Open ModalScreen.js and modify it.

Java
xxxxxxxxxx
1
66
 
1
import React from 'react'
2
import { StyleSheet, TouchableOpacity, Text, View } from 'react-native'
3
import { Ionicons } from '@expo/vector-icons'
4
5
function ModalScreen({ navigation }) {
6
  return (
7
    <View style={styles.container}>
8
      <View style={styles.innerContainer}>
9
        <View style={styles.closeButtonContainer}>
10
          <TouchableOpacity
11
            style={styles.closeButton}
12
            onPress={() => navigation.goBack()}>
13
            <Ionicons name='ios-close' color='#101010' size={40} />
14
          </TouchableOpacity>
15
        </View>
16
        <View style={styles.modalContainer}>
17
          <Text style={{ color: '#444', fontSize: 20 }}>
18
            What do you want to do?
19
          </Text>
20
        </View>
21
      </View>
22
    </View>
23
  )
24
}
25
26
const styles = StyleSheet.create({
27
  container: {
28
    flex: 1
29
  },
30
  innerContainer: {
31
    borderTopLeftRadius: 10,
32
    borderTopRightRadius: 10,
33
    justifyContent: 'flex-end',
34
    flexDirection: 'row',
35
    height: '30%',
36
    width: '100%',
37
    position: 'absolute',
38
    bottom: 0,
39
    right: 0,
40
    backgroundColor: '#fff'
41
  },
42
  closeButtonContainer: {
43
    position: 'absolute',
44
    alignItems: 'flex-end',
45
    right: 10
46
  },
47
  closeButton: {
48
    backgroundColor: '#d3d3d3',
49
    borderRadius: 20,
50
    width: 40,
51
    height: 40,
52
    top: 10,
53
    alignItems: 'center',
54
    justifyContent: 'center'
55
  },
56
  modalContainer: {
57
    justifyContent: 'center',
58
    alignItems: 'center',
59
    position: 'absolute',
60
    margin: 60,
61
    top: 10,
62
    left: 50
63
  }
64
})
65
66
export default ModalScreen


Here is the output you are going to get in the device after this step:

Smaller modal implemented

7. Adding a Text Input in the Custom Modal Screen

In this section, let’s add a text input component from the react-native core. This is going to allow the user to enter the name of the item they want to add to the list. For now, since we haven’t configured the Redux to manage the app state, let us use the hook useState to manage the component state locally.

Open ModalScreen.js and import TextInput from react-native core.

JavaScript
xxxxxxxxxx
1
 
1
import {
2
  StyleSheet,
3
  TouchableOpacity,
4
  Text,
5
  View,
6
  TextInput
7
} from 'react-native'


Next, inside the View that has the style of modalContainer add the following TextInput component as well as a touchable submit button. This touchable button is going to navigate back to the list screen when the user has entered a value in the input field.

JavaScript
xxxxxxxxxx
1
29
 
1
<View style={styles.modalContainer}>
2
  <Text style={{ color: '#444', fontSize: 20 }}>What do you want to do?</Text>
3
  <TextInput
4
    style={{
5
      height: 50,
6
      width: 200,
7
      padding: 5,
8
      borderColor: 'gray',
9
      borderBottomWidth: 1
10
    }}
11
    numberOfLines={1}
12
    onChangeText={value => setValue(value)}
13
    value={value}
14
    clearButtonMode='while-editing'
15
  />
16
  <TouchableOpacity
17
    style={{
18
      marginTop: 10,
19
      backgroundColor: 'blue',
20
      width: 50,
21
      height: 50,
22
      alignItems: 'center',
23
      justifyContent: 'center',
24
      borderRadius: 5
25
    }}
26
    onPress={() => navigation.navigate('List')}>
27
    <Ionicons name='ios-arrow-dropright-circle' size={40} color='#fff' />
28
  </TouchableOpacity>
29
</View


8. Add a Custom Header to the List Screen

Create a new file called Header.js inside the directory src/components. This functional component is going to display the header title in the List screen.

Add the following code snippet to the file you have just created:

JavaScript
xxxxxxxxxx
1
28
 
1
import React from 'react'
2
import { View, Text, StyleSheet } from 'react-native'
3
4
function Header(props) {
5
  const { title } = props
6
  return (
7
    <View style={styles.container}>
8
      <Text style={styles.text}>{title}</Text>
9
    </View>
10
  )
11
}
12
13
const styles = StyleSheet.create({
14
  container: {
15
    alignItems: 'center',
16
    justifyContent: 'center',
17
    backgroundColor: 'blue',
18
    height: 125,
19
    paddingTop: 20
20
  },
21
  text: {
22
    color: '#fff',
23
    fontSize: 28,
24
    fontWeight: '500'
25
  }
26
})
27
28
export default Header


Next, go to the ListScreen.js and import this functional component below the other statements.

JavaScript
xxxxxxxxxx
1
 
1
// after other import statements
2
import Header from '../components/Header'


Then, add the component to render before the floating button.

JavaScript
xxxxxxxxxx
1
 
1
function ListScreen({ navigation }) {
2
  return (
3
    <View style={styles.container}>
4
      <Header title={'List'} />
5
      {/* rest of the code remains same */}
6
    </View>
7
  )
8
}


In the simulator, you are going to get a header displayed as follows:

Header display

The Status bar doesn’t look good with the header’s background, right?

9. Change the StatusBar Appearance

To change the StatusBar appearance, let us import it from the react-native core API.

JavaScript
xxxxxxxxxx
1
 
1
import {
2
  StyleSheet,
3
  StatusBar,
4
  Text,
5
  View,
6
  TouchableOpacity
7
} from 'react-native'


Next, using React Fragment short hand with angle brackets, modify the return statement of ListScreen component as below:

JavaScript
xxxxxxxxxx
1
17
 
1
function ListScreen({ navigation }) {
2
  return (
3
    <>
4
      <StatusBar barStyle='light-content' />
5
      <View style={styles.container}>
6
        <Header title={'List'} />
7
        <View style={styles.fabContainer}>
8
          <TouchableOpacity
9
            onPress={() => navigation.navigate('Modal')}
10
            style={styles.fabButton}>
11
            <Ionicons name='ios-add' color='#fff' size={70} />
12
          </TouchableOpacity>
13
        </View>
14
      </View>
15
    </>
16
  )
17
}


You will now notice that the Status bar has a white appearance.

Header display changed

10. Add a List view

In this section, let’s implement the main view that is going to display a list of items. In ListScreen.js, add the following functional component called ListView.

JavaScript
 




xxxxxxxxxx
1
15


 
1
function ListView() {
2
  return (
3
    <View
4
      style={{
5
        backgroundColor: 'white',
6
        flex: 1,
7
        borderTopLeftRadius: 20,
8
        borderTopRightRadius: 20,
9
        paddingHorizontal: 20,
10
        paddingVertical: 20
11
      }}>
12
      <Text>Here goes list items</Text>
13
    </View>
14
  )
15
}



Then, modify the ListScreen to display it below the Header.

JavaScript
 




xxxxxxxxxx
1


 
1
<View style={styles.container}>
2
  <Header title={'List'} />
3
  <ListView />
4
  {/* rest of the code remains same */}
5
</View>



Go to the device you are running the app, and you are going to notice a major difference in its appearance.

Listview added

11. Creating a Root Reducer

Create a new directory called src/redux/ and inside it, a new file called reducer.js. This file is going to have the definition of action types, action creators and the only reducer we are going to create in this app. This reducer is going to be called rootReducer.

When using Redux to manage the state of the whole application, the state itself is represented by one JavaScript object. Think of this object as read-only (immutable), since you cannot make changes to this state or the object (which is represented in the form of a tree) directly. It requires an action to do so.

Actions are similar to events in Redux. They can be triggered in the button press, timers or network requests.

Start by defining an action type as below.

JavaScript
xxxxxxxxxx
1
 
1
export const ADD_ITEM = 'ADD_ITEM'


Then define the action creator called addItem that is going to take an item from the user’s input and add it to the list. This is the action creator function that we are going to trigger later.

JavaScript
xxxxxxxxxx
1
 
1
export const addItem = item => ({
2
  type: ADD_ITEM,
3
  payload: item
4
})


Define an initial state which is going to have an empty array called itemList. Whenever an action is triggered, the state of the application changes. The handling of the application’s state is done by the reducers.

This initial state is going to be passed as a parameter to the rootReducer. Calling the create action is going to invoke the logic defined for the same action type in the reducer.

Using a reducer, you either want to initiate the current app state or update it, without modifying the whole state on each action trigger. The spread operator returned in the action type ADD_ITEM indicates that.

To update the state, in our case, to add an item object to the itemList array, let us use the contact() that is going to return a new array whenever an item is added to the list. This also satisfies the redux philosophy of not mutating the state directly.

JavaScript
xxxxxxxxxx
1
21
 
1
const initialState = {
2
  itemList: []
3
}
4

          
5
const rootReducer = (state = initialState, action) => {
6
  switch (action.type) {
7
    case ADD_ITEM:
8
      return {
9
        ...state,
10
        itemList: state.itemList.concat({
11
          id: Math.random(),
12
          name: action.payload
13
        })
14
      }
15

          
16
    default:
17
      return state
18
  }
19
}
20

          
21
export default rootReducer


12. Configuring a Store

Create a new file src/redux/store.js. A store is an object that brings the actions and reducers together. This file is going to implement that.

The store provides and holds the state at the application level instead of individual components. Add the following code snippet to it:

JavaScript
xxxxxxxxxx
1
 
1
import { createStore } from 'redux'
2
import rootReducer from './reducer'
3

          
4
const store = createStore(rootReducer)
5

          
6
export default store


Now, to connect this store to the app, open App.js file and import the store from this file as well as the High Order Component Provider from react-redux npm package. This HOC helps you to pass the store down to the rest of the components of the current app.

JavaScript
xxxxxxxxxx
1
12
 
1
import React from 'react'
2
import { Provider as StateProvider } from 'react-redux'
3
import store from './src/redux/store'
4
import MainStackNavigator from './src/navigation/AppNavigator'
5

          
6
export default function App() {
7
  return (
8
    <StateProvider store={store}>
9
      <MainStackNavigator />
10
    </StateProvider>
11
  )
12
}


13. The useSelector Hook

To access state when managing it with Redux, the useSelector hook is provided in the library. It is similar to mapStateToProps argument that is passed inside the connect(). It allows you to extract data from the Redux store state using a selector function.

The major difference between the hook and the argument (the older way) is that the hook may return any value as a result, not just an object.

Inside ListScreen.js add the following import statement.

JavaScript
xxxxxxxxxx
1
 
1
import { useSelector } from 'react-redux'


Then, fetch the listItems array using the hook useSelector inside the ListView component. Also, modify its return statement by displaying a message if the list is empty or not.

JavaScript
xxxxxxxxxx
1
21
 
1
function ListView() {
2
  const listItems = useSelector(state => state.itemList)
3

          
4
  return (
5
    <View
6
      style={{
7
        backgroundColor: 'white',
8
        flex: 1,
9
        borderTopLeftRadius: 20,
10
        borderTopRightRadius: 20,
11
        paddingHorizontal: 20,
12
        paddingVertical: 20
13
      }}>
14
      {listItems.length !== 0 ? (
15
        <Text>Contains List items</Text>
16
      ) : (
17
        <Text style={{ fontSize: 30 }}>You list is empty :'(</Text>
18
      )}
19
    </View>
20
  )
21
}


Here is the output you are going to get:

adding list to application

14. Adding Items to the List by Dispatching an Action Creator

The useDispatch() hook completely refers to the dispatch function from the Redux store. This hook is used only when there is a need to dispatch an action. In the ModalScreen.js to add an item based on the value of TextInput, the state has to be updated. This can be done by triggering the action creator method called addItem defined when creating actions inside redux/reducer.js file.

Start by importing the following statements:

JavaScript
xxxxxxxxxx
1
 
1
import { useDispatch } from 'react-redux'
2
import { addItem } from '../redux/reducer'


Next, inside the ModalScreen component, create a helper method called onSaveNote which when triggered on submission of the text input, is going to trigger the action creator as well as take the user back to the List screen.

JavaScript
xxxxxxxxxx
1
 
1
const [value, setValue] = useState('')
2
const dispatch = useDispatch()
3
const onSaveNote = value => {
4
  dispatch(addItem(value))
5
  navigation.navigate('List')
6
}


Lastly, add this helper method as the value of onPress on the submission button.

JavaScript
xxxxxxxxxx
1
13
 
1
<TouchableOpacity
2
  style={{
3
    marginTop: 10,
4
    backgroundColor: 'blue',
5
    width: 50,
6
    height: 50,
7
    alignItems: 'center',
8
    justifyContent: 'center',
9
    borderRadius: 5
10
  }}
11
  onPress={() => onSaveNote(value)}>
12
  <Ionicons name='ios-arrow-dropright-circle' size={40} color='#fff' />
13
</TouchableOpacity>


15. Adding FlatList to Display the Items in the List

To display a list of items on List screen, open the file ListScreen.js and import the FlatList from react-native.

JavaScript
xxxxxxxxxx
1
 
1
import {
2
  StyleSheet,
3
  StatusBar,
4
  Text,
5
  View,
6
  TouchableOpacity,
7
  FlatList
8
} from 'react-native'


Then, modify the ListView render function as below:

JavaScript
xxxxxxxxxx
1
19
 
1
{
2
  listItems.length !== 0 ? (
3
    <FlatList
4
      data={listItems}
5
      keyExtractor={item => item.id.toString()}
6
      renderItem={({ item }) => (
7
        <View style={styles.listItemContainer}>
8
          <View style={styles.listItemMetaContainer}>
9
            <Text style={styles.itemTitle} numberOfLines={1}>
10
              {item.name}
11
            </Text>
12
          </View>
13
        </View>
14
      )}
15
    />
16
  ) : (
17
    <Text style={{ fontSize: 30 }}>You list is empty :'(</Text>
18
  )
19
}


16. Updating the Header

In this section, using the current app’s state, let us display the number of items in the list to be shown in the header as well. This can be done by using useSelector hook from react-redux.

Modify the file components/Header.js as the following:

JavaScript
xxxxxxxxxx
1
37
 
1
import React from 'react'
2
import { View, Text, StyleSheet } from 'react-native'
3
import { useSelector } from 'react-redux'
4

          
5
function Header(props) {
6
  const { title } = props
7
  const listItems = useSelector(state => state.itemList)
8

          
9
  return (
10
    <View style={styles.container}>
11
      <Text style={styles.title}>{title}</Text>
12
      <Text style={styles.subTitle}>Left: {listItems.length}</Text>
13
    </View>
14
  )
15
}
16

          
17
const styles = StyleSheet.create({
18
  container: {
19
    alignItems: 'center',
20
    justifyContent: 'center',
21
    backgroundColor: 'blue',
22
    height: 125,
23
    paddingTop: 20
24
  },
25
  title: {
26
    color: '#fff',
27
    fontSize: 28,
28
    fontWeight: '500'
29
  },
30
  subTitle: {
31
    paddingTop: 5,
32
    fontSize: 18,
33
    color: '#fff'
34
  }
35
})
36

          
37
export default Header


Here is the updated header bar when there is one item on the list.

adding item count to header

17. Removing an Item

Since we have gone through the process of understanding how redux hooks work with React Native apps, try adding a remove item button that is going to delete an item from the list as shown below.

removing an item from list

If you need any help, you can come back to the source code below.

Here is the updated redux/reducer file that has action type REMOVE_ITEM.

JavaScript
xxxxxxxxxx
1
39
 
1
export const ADD_ITEM = 'ADD_ITEM'
2
export const REMOVE_ITEM = 'REMOVE_ITEM'
3

          
4
export const addItem = item => ({
5
  type: ADD_ITEM,
6
  payload: item
7
})
8

          
9
export const removeItem = id => ({
10
  type: REMOVE_ITEM,
11
  payload: id
12
})
13

          
14
const initialState = {
15
  itemList: []
16
}
17

          
18
const rootReducer = (state = initialState, action) => {
19
  switch (action.type) {
20
    case ADD_ITEM:
21
      return {
22
        ...state,
23
        itemList: state.itemList.concat({
24
          id: Math.random(),
25
          name: action.payload
26
        })
27
      }
28
    case REMOVE_ITEM:
29
      return {
30
        ...state,
31
        itemList: state.itemList.filter(item => item.id !== action.payload)
32
      }
33

          
34
    default:
35
      return state
36
  }
37
}
38

          
39
export default rootReducer


Also, here is the updated ListScreen.js where you add the button to remove items with corresponding styles.

To trigger an action, you will have to make use of useDispatch() hook.

JavaScript
x
116
 
1
import React from 'react'
2
import {
3
  StyleSheet,
4
  StatusBar,
5
  Text,
6
  View,
7
  TouchableOpacity,
8
  FlatList
9
} from 'react-native'
10
import { Ionicons } from '@expo/vector-icons'
11
import { useSelector, useDispatch } from 'react-redux'
12
import { removeItem } from '../redux/reducer'
13

          
14
import Header from '../components/Header'
15

          
16
function ListView() {
17
  const listItems = useSelector(state => state.itemList)
18
  console.log({ listItems })
19

          
20
  const dispatch = useDispatch()
21

          
22
  return (
23
    <View
24
      style={{
25
        backgroundColor: 'white',
26
        flex: 1,
27
        borderTopLeftRadius: 20,
28
        borderTopRightRadius: 20,
29
        paddingHorizontal: 20,
30
        paddingVertical: 20
31
      }}>
32
      {listItems.length !== 0 ? (
33
        <FlatList
34
          data={listItems}
35
          keyExtractor={item => item.id.toString()}
36
          renderItem={({ item }) => (
37
            <View style={styles.listItemContainer}>
38
              <Text style={styles.itemTitle} numberOfLines={1}>
39
                {item.name}
40
              </Text>
41
              <TouchableOpacity
42
                onPress={() => dispatch(removeItem(item.id))}
43
                style={styles.button}>
44
                <Ionicons name='ios-trash' color='#fff' size={20} />
45
              </TouchableOpacity>
46
            </View>
47
          )}
48
        />
49
      ) : (
50
        <Text style={{ fontSize: 30 }}>You list is empty :'(</Text>
51
      )}
52
    </View>
53
  )
54
}
55

          
56
function ListScreen({ navigation }) {
57
  return (
58
    <>
59
      <StatusBar barStyle='light-content' />
60
      <View style={styles.container}>
61
        <Header title={'List'} />
62
        <ListView />
63
        <View style={styles.fabContainer}>
64
          <TouchableOpacity
65
            onPress={() => navigation.navigate('Modal')}
66
            style={styles.fabButton}>
67
            <Ionicons name='ios-add' color='#fff' size={70} />
68
          </TouchableOpacity>
69
        </View>
70
      </View>
71
    </>
72
  )
73
}
74

          
75
const styles = StyleSheet.create({
76
  container: {
77
    flex: 1,
78
    backgroundColor: 'blue'
79
  },
80
  fabContainer: {
81
    justifyContent: 'flex-end',
82
    flexDirection: 'row',
83
    position: 'absolute',
84
    right: 10,
85
    bottom: 20
86
  },
87
  fabButton: {
88
    backgroundColor: 'blue',
89
    borderRadius: 35,
90
    width: 70,
91
    height: 70,
92
    alignItems: 'center',
93
    justifyContent: 'center'
94
  },
95
  listItemContainer: {
96
    flex: 1,
97
    flexDirection: 'row',
98
    paddingTop: 10,
99
    paddingBottom: 5,
100
    paddingRight: 5,
101
    justifyContent: 'space-between',
102
    width: '100%',
103
    borderBottomWidth: 0.25
104
  },
105
  itemTitle: {
106
    fontSize: 22,
107
    fontWeight: '400'
108
  },
109
  button: {
110
    borderRadius: 8,
111
    backgroundColor: '#ff333390',
112
    padding: 5
113
  }
114
})
115

          
116
export default ListScreen


Here is the final output of the demo app:

Final app

Conclusion

The addition to hooks in react-redux such as useSelector and useDispatch reduces the need to write plentiful boilerplate code and also provides the advantage to use functional components.

For advanced usage of Hooks with Redux, you can check out the official documentation here.

Hopefully, you now have a grasp of how to work with Redux in React Native apps using Hooks, as well as a better understanding of the basics of react navigation. If you enjoyed this React Native tutorial, please share it with your friends. Happy Coding!

React Native React (JavaScript library) app JavaScript Hook

Published at DZone with permission of krissanawatt kaewsanmunag. See the original article here.

Opinions expressed by DZone contributors are their own.

Related

  • Navigation in a React Native Web Application
  • How to Build Scalable Mobile Apps With React Native: A Step-by-Step Guide
  • Mastering React App Configuration With Webpack
  • How to Build a React Native Chat App for Android

Partner Resources

×

Comments
Oops! Something Went Wrong

The likes didn't load as expected. Please refresh the page and try again.

ABOUT US

  • About DZone
  • Support and feedback
  • Community research
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 100
  • Nashville, TN 37211
  • support@dzone.com

Let's be friends:

Likes
There are no likes...yet! 👀
Be the first to like this post!
It looks like you're not logged in.
Sign in to see who liked this post!