In today’s digital landscape, knowing how to build a full-stack application is a crucial skill for any aspiring web developer. Whether you’re new to development or expanding your JavaScript skills, React JS and Node.js are excellent tools for crafting dynamic, modern web applications. This guide will walk you through the steps of building your first full-stack application using React for the front end and Node.js for the back end.
Let’s dive in!
Why Choose React and Node.js?
React is a popular JavaScript library for building user interfaces, particularly single-page applications (SPAs). Its component-based architecture makes it perfect for creating dynamic, reusable UI components.
On the other hand, Node.js allows you to build server-side applications using JavaScript. With the power of Express.js, a minimal and flexible Node.js framework, you can create a REST API that communicates seamlessly with your React frontend.
Together, React and Node.js make a powerful duo for full-stack web development.
Planning Your Application
Before jumping into code, let’s plan the features of the full-stack application we’ll build. For this tutorial, we’ll create a simple task manager where users can:
- Create new tasks
- View a list of tasks
- Mark tasks as complete
- Delete tasks
This will allow you to work with core full-stack concepts such as CRUD operations (Create, Read, Update, Delete), REST APIs, and database interactions.
Setting Up the Backend: Node.js and Express
- Initialize the Project
First, create a new folder for your backend and initialize it with npm init
to generate a package.json
file.
mkdir task-manager-backend
cd task-manager-backend
npm init -y
- Install Dependencies
Next, install Express.js to handle your server and API routes, and nodemon
for automatically restarting the server when files change.
npm install express
npm install -D nodemon
Update the package.json
file to use nodemon
:
"scripts": {
"start": "nodemon index.js"
}
- Create a Basic Server
Create an index.js
file and write a simple server that listens on port 5000.
const express = require('express');
const app = express();
app.use(express.json());
app.get('/', (req, res) => {
res.send('Welcome to the Task Manager API');
});
app.listen(5000, () => {
console.log('Server running on port 5000');
});
Run the server with:
npm start
Navigate to http://localhost:5000/
in your browser, and you should see the welcome message from your server.
- Define RESTful Routes
Create routes for managing tasks (create, read, update, delete). We’ll use a simple array to store tasks temporarily.
let tasks = [];
app.post('/tasks', (req, res) => {
const task = { id: tasks.length + 1, text: req.body.text, completed: false };
tasks.push(task);
res.status(201).send(task);
});
app.get('/tasks', (req, res) => {
res.send(tasks);
});
app.patch('/tasks/:id', (req, res) => {
const task = tasks.find(t => t.id === parseInt(req.params.id));
if (!task) return res.status(404).send('Task not found.');
task.completed = req.body.completed;
res.send(task);
});
app.delete('/tasks/:id', (req, res) => {
const taskIndex = tasks.findIndex(t => t.id === parseInt(req.params.id));
if (taskIndex === -1) return res.status(404).send('Task not found.');
const deletedTask = tasks.splice(taskIndex, 1);
res.send(deletedTask);
});
With these routes in place, you can now create, retrieve, update, and delete tasks via the API.
Building the Frontend: React
Now that the backend is set up, let’s move to the React frontend.
- Create a React App
Navigate back to the root directory and create a new React application using create-react-app
.
npx create-react-app task-manager-frontend
cd task-manager-frontend
- Install Axios
Axios is a promise-based HTTP client that will help us make API calls from our React app to the Node.js backend.
npm install axios
- Creating the UI
Open the src
folder, and let’s first create a basic UI for adding and displaying tasks. Start by setting up the state to hold the list of tasks and a simple form for adding new tasks.
import React, { useState, useEffect } from 'react';
import axios from 'axios';
const App = () => {
const [tasks, setTasks] = useState([]);
const [taskText, setTaskText] = useState('');
useEffect(() => {
fetchTasks();
}, []);
const fetchTasks = async () => {
const response = await axios.get('http://localhost:5000/tasks');
setTasks(response.data);
};
const addTask = async () => {
const newTask = { text: taskText };
const response = await axios.post('http://localhost:5000/tasks', newTask);
setTasks([...tasks, response.data]);
setTaskText('');
};
return (
<div>
<h1>Task Manager</h1>
<input
type="text"
value={taskText}
onChange={(e) => setTaskText(e.target.value)}
placeholder="Add a new task"
/>
<button onClick={addTask}>Add Task</button>
<ul>
{tasks.map((task) => (
<li key={task.id}>
{task.text} - {task.completed ? 'Completed' : 'Pending'}
</li>
))}
</ul>
</div>
);
};
export default App;
Here’s what’s happening:
- We’re using
useState
to store tasks and the new task input. - The
fetchTasks
function fetches tasks from the backend API using Axios. addTask
sends a POST request to the API to create a new task.
- Mark Tasks as Complete
Next, let’s allow users to mark tasks as complete. In the task list, add a button to toggle the task’s status.
const toggleTaskCompletion = async (id, completed) => {
await axios.patch(`http://localhost:5000/tasks/${id}`, { completed: !completed });
fetchTasks();
};
return (
<ul>
{tasks.map((task) => (
<li key={task.id}>
{task.text} - {task.completed ? 'Completed' : 'Pending'}
<button onClick={() => toggleTaskCompletion(task.id, task.completed)}>
{task.completed ? 'Undo' : 'Complete'}
</button>
</li>
))}
</ul>
);
- Delete Tasks
Finally, add functionality to delete tasks:
const deleteTask = async (id) => {
await axios.delete(`http://localhost:5000/tasks/${id}`);
fetchTasks();
};
return (
<ul>
{tasks.map((task) => (
<li key={task.id}>
{task.text} - {task.completed ? 'Completed' : 'Pending'}
<button onClick={() => toggleTaskCompletion(task.id, task.completed)}>
{task.completed ? 'Undo' : 'Complete'}
</button>
<button onClick={() => deleteTask(task.id)}>Delete</button>
</li>
))}
</ul>
);
Conclusion
Congratulations! You’ve built your first full-stack application using React and Node.js. While this task manager is simple, you now have a solid understanding of how the front end and back end communicate through APIs, how to work with React’s state, and how to perform CRUD operations with a Node.js server. You can expand this project by adding a database (like MongoDB), user authentication, or additional features to solidify your skills.