Connecting React Native to Node.js
Now that you’ve built both the backend with Node.js and the frontend with React Native, it’s time to bring these two together. Imagine your app as a restaurant: the backend (Node.js) is the kitchen where the food is prepared, and the frontend (React Native) is the dining room where customers order and receive their food. The waitstaff (API) connects the two, carrying information back and forth. In this chapter, you’re going to make that connection and get your app to communicate with your backend.
By the end of this chapter, your React Native app will be able to send requests to the backend, retrieve data, and display it in the app. This will unlock a ton of possibilities, like fetching user profiles, handling login systems, displaying content, and much more.
Ready? Let’s make some magic happen!
Step 1: Setting Up Axios – Your API Butler
To connect your React Native app to your Node.js backend, we’ll be using a library called Axios. Axios is a popular and easy-to-use tool for making HTTP requests. You can think of it as your app’s butler, handling communication with the server.
Installing Axios
First, we need to install Axios in your React Native project. Open your terminal and navigate to your project directory, then run the following command:
npm install axios
That’s it! Axios is now part of your project, ready to send requests and receive responses.
Step 2: Setting Up Your Backend API
Before we dive into coding on the frontend, let’s quickly review your Node.js backend. In Chapter 2, we created a simple Node.js server using Express. We set up some basic routes to handle requests from the frontend.
Here’s a quick refresher of what your users route looks like:
const express = require('express');
const app = express();
const PORT = 3000;
// Middleware to handle JSON
app.use(express.json());
// Simulated database
const users = [
{ id: 1, name: 'John Doe', email: '[email protected]' },
{ id: 2, name: 'Jane Smith', email: '[email protected]' },
];
// GET request to fetch all users
app.get('/users', (req, res) => {
res.json(users);
});
// Start the server
app.listen(PORT, () => {
console.log(`Server running at http://localhost:${PORT}`);
});
This backend is up and running at http://localhost:3000
. It’s simple but perfect for our example—your mobile app will soon fetch the list of users from this API and display them on the screen.
Step 3: Making Your First API Call from React Native
Now, let’s switch to your React Native app. You’ll fetch data from your Node.js backend and display it in your app using Axios.
Fetching Data with Axios
To get started, open your App.js
file in your React Native project, and let’s modify it to fetch user data from the backend.
Here’s the code to fetch data from the /users
endpoint:
import React, { useEffect, useState } from 'react';
import { StyleSheet, Text, View, FlatList } from 'react-native';
import axios from 'axios';
export default function App() {
const [users, setUsers] = useState([]);
useEffect(() => {
// Fetch data from the backend
axios.get('http://localhost:3000/users')
.then(response => {
setUsers(response.data);
})
.catch(error => {
console.error('Error fetching users:', error);
});
}, []);
return (
<View style={styles.container}>
<Text style={styles.title}>User List</Text>
<FlatList
data={users}
keyExtractor={item => item.id.toString()}
renderItem={({ item }) => (
<Text style={styles.user}>{item.name} - {item.email}</Text>
)}
/>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
paddingTop: 50,
},
title: {
fontSize: 24,
fontWeight: 'bold',
marginBottom: 20,
},
user: {
fontSize: 18,
marginBottom: 10,
},
});
Let’s break this down:
- useEffect: We’re using React’s
useEffect
hook to fetch data as soon as the component is mounted. The empty dependency array ([]
) ensures this only happens once when the app loads. - Axios request: Inside
useEffect
, we make a GET request to the/users
endpoint using Axios. When the response comes back, we store the user data in theusers
state usingsetUsers
. - FlatList: We use a
FlatList
component to display the list of users. Each user’s name and email are rendered inside aText
component.
What Does This Do?
When you run this code, your app will make a request to your Node.js server at http://localhost:3000/users
. It will receive the user data from the server and display it in a nice list on the screen.
Step 4: Dealing with the Mobile Environment
Changing localhost to Your IP Address
If you try running the app on your mobile device, you might notice it doesn’t work as expected. That’s because localhost
refers to your computer’s own address, but your phone doesn’t know where to find that. To fix this, you’ll need to replace localhost
with your computer’s local IP address.
Here’s how to find your local IP:
- On Windows, open the command prompt and type
ipconfig
. Look for the IPv4 Address. - On Mac or Linux, open the terminal and type
ifconfig
orip a
. Look for the IP address under your active network.
Once you have your local IP address, replace localhost
in your Axios request like this:
axios.get('http://192.168.x.x:3000/users') // Replace with your actual IP
Now your mobile device will know where to find your server.
Step 5: Testing API Calls with Postman
Before connecting your React Native app to your Node.js backend, it’s a good idea to test your API using a tool like Postman. This helps you ensure that your backend is working correctly before involving the frontend.
Setting Up Postman
- Download Postman: If you don’t already have Postman installed, head over to the Postman website and download the app.
- Test the
/users
endpoint: Open Postman, and in the address bar, typehttp://localhost:3000/users
. Hit Send, and you should see a list of users appear in the response. If everything is working, you’re good to go!
Step 6: Handling User Input and Sending Data to the Backend
Let’s take things a step further. You’ll now allow the user to input data into your React Native app and send it to your Node.js backend using a POST request.
Adding a Form to Your App
Modify your App.js
file to include a form where users can enter their name and email. When the user submits the form, you’ll send that data to your Node.js backend.
Here’s the updated code:
import React, { useState } from 'react';
import { StyleSheet, Text, View, TextInput, Button, FlatList } from 'react-native';
import axios from 'axios';
export default function App() {
const [users, setUsers] = useState([]);
const [name, setName] = useState('');
const [email, setEmail] = useState('');
const fetchUsers = () => {
axios.get('http://192.168.x.x:3000/users')
.then(response => {
setUsers(response.data);
})
.catch(error => {
console.error('Error fetching users:', error);
});
};
const addUser = () => {
axios.post('http://192.168.x.x:3000/users', { name, email })
.then(() => {
fetchUsers(); // Refresh the list after adding a user
setName('');
setEmail('');
})
.catch(error => {
console.error('Error adding user:', error);
});
};
return (
<View style={styles.container}>
<Text style={styles.title}>User List</Text>
<FlatList
data={users}
keyExtractor={item => item.id.toString()}
renderItem={({ item }) => (
<Text style={styles.user}>{item.name} - {item.email}</Text>
)}
/>
<TextInput
style={styles.input}
placeholder="Enter name"
value={name}
onChangeText={setName}
/>
<TextInput
style={styles.input}
placeholder="Enter email"
value={email}
onChangeText={setEmail}
/>
<Button title="Add User" onPress={addUser} />
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
paddingTop: 50,
},
title: {
fontSize: 24,
fontWeight: 'bold',
marginBottom: 20,
},
user: {
fontSize: 18,
marginBottom: 10,
},
input: {
width: '80%',
height: 40,
borderColor: 'gray',
borderWidth: 1,
marginBottom: 10,
paddingHorizontal: 10,
},
});
Explanation:
- TextInput: We’ve added two input fields (
TextInput
) for the user’s name and email. The values are stored in thename
andemail
states. - addUser: When the user submits the form, the
addUser
function sends a POST request to the backend with the user’s name and email. - fetchUsers: After adding a user, we fetch the updated user list and display it in the
FlatList
.
Now, when you run your app, you’ll be able to add users through the form, and they’ll be sent to your backend.
Step 7: Handling Errors and Edge Cases
It’s always important to handle potential errors in your app. For example, what happens if the user submits the form without entering a name or email? Or what if the server is down?
You can improve your app by adding simple error handling like this:
const addUser = () => {
if (!name || !email) {
alert('Please enter both a name and an email.');
return;
}
axios.post('http://192.168.x.x:3000/users', { name, email })
.then(() => {
fetchUsers(); // Refresh the list after adding a user
setName('');
setEmail('');
})
.catch(error => {
console.error('Error adding user:', error);
alert('Something went wrong. Please try again.');
});
};
Now, the app will alert the user if they try to submit an empty form, and it will handle server errors more gracefully.
Step 8: The Magic is Happening!
Congratulations! You’ve just made the magic happen. Your React Native app is now fully connected to your Node.js backend, capable of sending and receiving data. This opens up endless possibilities for what you can do next.
In the upcoming chapters, we’ll dive deeper into more advanced features, like authentication, working with databases, and even deploying your app to a live server.
For now, take a moment to celebrate—you’ve come a long way. You’re no longer just playing in the playground—you’re building real, powerful mobile apps that communicate with servers and handle dynamic data. Well done!
🚀