Building modern web applications can be challenging, especially for beginners. With so many frameworks, libraries, and tools to choose from, it’s hard to know where to start. React.js has quickly become one of the most popular open-source JavaScript libraries for building user interfaces. Its declarative, component-based architecture makes it easy to build complex UIs from small, reusable pieces of code.
In this beginner’s guide, we’ll walk through the fundamentals of React.js and build a simple web application from scratch. We’ll cover:
- What React is and why it’s useful
- Setting up a React development environment
- JSX syntax
- Components, props, and state
- Handling events
- Lifecycle methods
- Fetching data
- Routing
- Deploying a React app
By the end, you’ll have a solid understanding of React and be ready to build your own applications!
What is React?
React is an open-source JavaScript library created by Facebook for building fast, interactive user interfaces for web and mobile applications.
Unlike traditional web frameworks that manipulate the DOM directly, React uses a virtual DOM where it does all the work before making changes to the real DOM. This makes React very performant compared to traditional frameworks.
Some key features of React include:
- Declarative: React uses a declarative paradigm that makes code more predictable and easier to debug. You simply declare what each component should look like for any given state.
- Component-based: Build encapsulated components that manage their own state and compose them to make complex UIs. Since component logic is written in JavaScript instead of templates, you can easily pass rich data through your app and keep state out of the DOM.
- Learn Once, Write Anywhere: React can be used to build web, mobile, VR and even desktop applications. The same components can be reused across different platforms.
So in summary, React allows developers to build reusable UI components that can be composed together to build complex and interactive web applications. Its popularity stems from its excellent performance, flexibility, and ability to integrate with other libraries.

Setting Up a React Development Environment
Before we start building our React app, we need to set up a development environment. Here are the basic tools we’ll need:
Node.js and npm
Node.js is a JavaScript runtime that allows us to run JavaScript on the server. It comes bundled with npm
, a package manager for installing JavaScript modules.
You’ll need to have Node.js (version 10 or later) installed on your system to build React applications. Download and install the latest version of Node from nodejs.org.
Create React App
Create React App is an officially supported way to create single-page React applications. It sets up a modern React project for you with no configuration needed.
To get started, you’ll need to first install Create React App globally:
npm install -g create-react-app
Now you can generate a new project by running:
create-react-app my-app
This will create a new folder called my-app
and install all the dependencies you need to get started.
Text Editor
You’ll want a good text editor to write React code. Popular options include Visual Studio Code, Atom, and Sublime Text.
Browser
Make sure you have an updated browser like Google Chrome or Firefox installed. We’ll use this to run and test our React app locally.
Okay, now we have our development environment setup – let’s dive into some React code!
JSX Syntax
React uses a syntax extension to JavaScript called JSX that allows you to write HTML-like elements in your JavaScript code. This is what React components are made of.
Here’s a simple example of valid JSX:
const element = <h1>Hello, world!</h1>;
This JSX will render as a <h1>
element containing the text “Hello, world!”.
But JSX has a key difference from HTML – it has the full power of JavaScript behind it! We can embed any JavaScript expressions by wrapping them in curly braces:
const name = 'John';
const element = <h1>Hello, {name}</h1>;
The {name}
expression will be evaluated and inserted into the JSX.
JSX provides a familiar syntax for defining tree structures with attributes that translate well to HTML elements. Under the hood, JSX is translated into regular JavaScript function calls and objects.
But JSX is not a requirement for using React – it’s just a helpful tool that makes code easier to read and write.
React Components
The building blocks of any React app are components. A component is a reusable, modular piece of code that encapsulates UI logic and markup.
We define components in React using classes or functions. Here’s an example of a simple Welcome
component as a function:
function Welcome(props) {
return <h1>Hello, {props.name}</h1>;
}
Components accept inputs called props
– short for properties. Here the Welcome
component expects a name
prop and renders an <h1>
element displaying the name.
We can render this component into the DOM like so:
const element = <Welcome name="Sara" />;
When React sees an element representing a user-defined component, it will pass the JSX attributes to that component as a single object called props
.
This allows components to be reused with different data – we can render the Welcome
component many times with different names.
Components can be broken down further into smaller components, allowing us to compose complex UIs out of simple building blocks.
5 Ways to Improve Your Programming Skills 2023
Props and State
There are two types of data that control a component: props
and state
.
Props
props
(short for properties) are data passed into a component by its parent component. Props are immutable – they should never be changed inside the child component.
For example, the Welcome
component above accepts a name
prop and displays it:
function Welcome(props) {
return <h1>Hello, {props.name}</h1>;
}
const element = <Welcome name="Sara" />;
Props allow parent components to pass data down to child components.
State
state
is data that is owned and managed by the component. State can be changed, triggering a re-render of the component.
State should be the “source of truth” for a component – the minimal representation of its data at a given point in time.
Here’s an example of a Timer
component that maintains its own state:
import React, { useState, useEffect } from 'react';
function Timer() {
const [seconds, setSeconds] = useState(0);
useEffect(() => {
const interval = setInterval(() => {
setSeconds((prevSeconds) => prevSeconds + 1);
}, 1000);
return () => {
clearInterval(interval);
};
}, []);
return (
<div>
Seconds: {seconds}
</div>
);
}
export default Timer;
The Timer
component stores the current seconds
value in its state. When the state updates, the component re-renders, displaying the new seconds
count.
State allows components to manage values and update what’s rendered as data changes over time.
Handling Events
React components can respond to user events like clicks, submits, key presses etc.
We can attach event handlers to elements in JSX using camelCase names:
function Button(props) {
function handleClick() {
console.log("You clicked me!");
}
return (
<button onClick={handleClick}>
Click Me
</button>
);
}
Here the handleClick
method will be called when the button is clicked.
Event handlers in React have access to the original DOM event via e
, so we can access details like the target element:
function Button(props) {
function handleClick(e) {
console.log(e.target); // the button element
}
// ...
We can pass custom arguments to handlers by wrapping them in another function:
function Button(props) {
function handleClick(message) {
console.log(message)
}
return (
<button onClick={() => handleClick('Hello!')}>
Click Me
</button>
);
}
Now handleClick
receives “Hello!” when clicked.
This allows flexible, reusable event handlers.
Component Lifecycle
Components go through a series of lifecycle methods during their time in your app. We can hook into these methods to run code at specific points.
Three common lifecycle methods are:
componentDidMount
– After initial rendercomponentDidUpdate
– After update rendercomponentWillUnmount
– Before unmounting
For example, we can setup a timer whenever Timer
mounts:
import React, { useState, useEffect } from 'react';
function Timer() {
const [seconds, setSeconds] = useState(0);
useEffect(() => {
const timerId = setInterval(() => {
setSeconds(prevSeconds => prevSeconds + 1);
}, 1000);
return () => {
clearInterval(timerId);
};
}, []);
//...
return (
// JSX for your Timer component
);
}
export default Timer;
The Timer
sets up the interval each time it renders.
Then we can clean it up with componentWillUnmount
:
componentWillUnmount() {
clearInterval(this.timer);
}
Lifecycle methods allow side effects like data fetching, subscriptions and more.
Fetching Data
Many React apps need to fetch data from an API. There are several ways to add data fetching to components:
- Fetch data in
componentDidMount
- Use the
useEffect
hook (in function components) - Render request status – loading, success, error
- Store data in state
- Trigger re-renders when data changes
Here’s a simple example using componentDidMount
:
import React, { useState, useEffect } from 'react';
function UserData() {
const [loading, setLoading] = useState(false);
const [data, setData] = useState(null);
useEffect(() => {
setLoading(true);
fetch('/api/user')
.then(response => response.json())
.then(data => {
setLoading(false);
setData(data);
});
}, []);
if (loading) {
return <div>Loading...</div>;
}
if (!data) {
return <div>No user data</div>;
}
// Show user data
return <div>{data.name}</div>;
}
export default UserData;
The key aspects are:
- Set
loading
state before fetch - Fetch data in
componentDidMount
- Update state when data returns
- Render different UI based on fetch status
There are more robust ways to manage network requests and data, but this covers the basics.
Routing
Routing allows us to display different components/views based on the URL.
The most popular router for React is React Router.
First, wrap the app in a <Router>
component.
Then we can add <Route>
s to map URL paths to components:
import { BrowserRouter as Router, Route } from 'react-router-dom';
function App() {
return (
<Router>
<div>
<Route path="/about">
<About />
</Route>
<Route path="/contact">
<Contact />
</Route>
</div>
</Router>
);
}
Now /about
will show the About
component, and /contact
will show Contact
.
The <Link>
component renders a clickable link:
function Home() {
return (
<div>
<h1>Home</h1>
<Link to="/about">About</Link>
</div>
);
}
This keeps your UI in sync with the URL without needing page refreshes.
There are more advanced routing techniques, but this covers the basics!
Deploying a React App
Once our React app is ready, we need to deploy it so others can access it. Here are a few options:
Static Hosting
Services like Vercel, Netlify, and AWS Amplify make it easy to deploy static sites and single page apps.
With Create React App, running npm run build
will generate static HTML, CSS, and JS bundles ready to deploy.
PaaS (Platform as a Service)
Platforms like Heroku allow you to deploy the full Node server for your React app in minutes. Often requires minimal config.
IaaS (Infrastructure as a Service)
Services like AWS EC2 provide flexible server infrastructure to deploy apps to your own remote machines.
Managed Containers
AWS ECS and Google Cloud Run manage container deployments and auto-scaling. Useful for large, complex apps.
There are many other great hosting options – these are just a few of the most popular!
Next Steps
Congratulations! You now have a solid understanding of the React fundamentals.
To recap:
- React is a declarative, efficient way to build modern UIs
- Components encapsulate UI code into small, reusable pieces
- JSX is a React component syntax that looks like HTML
- Props pass data to child components as read-only
- State manages data within a component as private
- Handlers respond to user events
- Lifecycle methods are called at key points
- Fetch data and route between views
- Deploy apps to static and server hosts
Some recommended next steps to improve your React skills:
- Get hands-on experience building sample projects
- Learn React hooks for stateful logic
- Work with tools like Redux for state management
- Look into TypeScript for static typing
- Try Next.js for server-side rendering
- Explore React Native for mobile development
React is a massive ecosystem – there’s always more to learn. But you now have the foundation to build awesome applications. Keep it up!