React is a JavaScript library for building user interfaces. It uses a declarative approach, based on reusable components.
Introduction to React
Create a New Project
Create React App is the official tool for creating React projects without manual configurations.
npx create-react-app project-name
cd project-name
npm start
Installing Dependencies
npm install package-name
Basic Project Structure
When creating a project, the common structure includes:
src/
- Directory with components and logic.public/
- Public files (HTML).node_modules/
- Installed dependencies.
JSX
JSX is a syntax extension for JavaScript that allows writing HTML within JS.
Basic Syntax
const element = <h1>Hello World</h1>;
Expressions in JSX
You can include JavaScript expressions within curly braces {}
:
const name = "John";
const element = <h1>Hello, {name}!</h1>;
Attributes
const element = <img src="image.jpg" alt="Description" />;
Components
Functional Component
A functional component is a JavaScript function that returns JSX.
const Component = () => {
return <div>This is a functional component.</div>;
};
Class Component
Class components allow using the React lifecycle.
import React, { Component } from 'react';
class MyComponent extends Component {
render() {
return <h1>Hello from a class component!</h1>;
}
}
export default MyComponent;
Event Handling
React handles events similarly to JavaScript, but with some differences. Event names are written in camelCase, and you must pass a function as the value.
const handleClick = () => {
alert('Button clicked');
};
const MyComponent = () => (
<button onClick={handleClick}>Click me</button>
);
Conditional Rendering
Ternary Operators
const MyComponent = ({ show }) => (
<div>
{show ? <p>Show</p> : <p>Hide</p>}
</div>
);
&& Operator
const MyComponent = ({ show }) => (
<div>
{show && <p>Show</p>}
</div>
);
Collections
Rendering Lists
To render lists in React, use the map()
method and provide a unique key to each item.
const items = ['Item 1', 'Item 2', 'Item 3'];
function List() {
return (
<ul>
{items.map((item, index) => (
<li key={index}>{item}</li>
))}
</ul>
);
}
Props and State
Props
props
(properties) are the data passed from a parent component to a child (to make them more dynamic and reusable)
function Greeting(props) {
return <h1>Hello, {props.name}!</h1>;
}
// Using the component
<Greeting name="John" />;
Default Props
Greeting.defaultProps = {
name: 'Unknown',
};
State
The useState
hook allows managing state within functional components.
import React, { useState } from 'react';
function Counter() {
const [count, setCount] = useState(0);
return (
<div>
<p>{count}</p>
<button onClick={() => setCount(count + 1)}>Increase</button>
</div>
);
}
State in Class Components
class Counter extends React.Component {
constructor(props) {
super(props);
this.state = { count: 0 };
}
increase = () => {
this.setState({ count: this.state.count + 1 });
};
render() {
return (
<div>
<p>{this.state.count}</p>
<button onClick={this.increase}>Increase</button>
</div>
);
}
}
Hooks
Side Effects
The useEffect
hook allows performing side effects in functional components, such as managing subscriptions or manipulating the DOM.
import React, { useEffect, useState } from 'react';
function Data() {
const [data, setData] = useState([]);
useEffect(() => {
fetch('https://api.example.com/data')
.then(response => response.json())
.then(data => setData(data));
}, []); // [] means the effect runs only once.
return <div>{data.length ? data[0].name : 'Loading...'}</div>;
}
Cleanup Effects
You can return a function in useEffect
to clean up effects (like an event listener).
useEffect(() => {
const handleResize = () => console.log(window.innerWidth);
window.addEventListener('resize', handleResize);
return () => window.removeEventListener('resize', handleResize);
}, []);
Using Contexts to Share State
useContext
allows sharing data between multiple components without manually passing props.
import React, { createContext, useContext } from 'react';
const ThemeContext = createContext('dark');
function App() {
return (
<ThemeContext.Provider value="light">
<Child />
</ThemeContext.Provider>
);
}
function Child() {
const theme = useContext(ThemeContext);
return <div>The current theme is {theme}</div>;
}
State Management with useReducer
useReducer
is useful for managing more complex states, such as in forms.
import React, { useReducer } from 'react';
const initialState = { count: 0 };
function reducer(state, action) {
switch (action.type) {
case 'increment':
return { count: state.count + 1 };
case 'decrement':
return { count: state.count - 1 };
default:
return state;
}
}
function Counter() {
const [state, dispatch] = useReducer(reducer, initialState);
return (
<div>
<p>{state.count}</p>
<button onClick={() => dispatch({ type: 'increment' })}>+</button>
<button onClick={() => dispatch({ type: 'decrement' })}>-</button>
</div>
);
}
Component Lifecycle
Mounting
When the component is added to the DOM. Examples: componentDidMount
.
Updating
When state or props change. Examples: componentDidUpdate
.
Unmounting
When the component is removed. Examples: componentWillUnmount
.
class MyComponent extends React.Component {
componentDidMount() {
console.log('Component mounted');
}
componentDidUpdate() {
console.log('Component updated');
}
componentWillUnmount() {
console.log('Component unmounted');
}
render() {
return <div>Component with lifecycle</div>;
}
}
Event Handling
Adding Events to a Component
React normalizes events like onClick
, onChange
, etc.
function Button() {
const handleClick = () => {
alert('Button clicked');
};
return <button onClick={handleClick}>Click here</button>;
}
Form Handling
Controlling Forms in React
The state of the form can be managed using useState
.
import React, { useState } from 'react';
function Form() {
const [name, setName] = useState('');
const handleSubmit = (e) => {
e.preventDefault();
alert(`The name is: ${name}`);
};
return (
<form onSubmit={handleSubmit}>
<input
type="text"
value={name}
onChange={(e) => setName(e.target.value)}
/>
<button type="submit">Send</button>
</form>
);
}
Styles in React
Inline Styles
const style = { color: 'red', fontSize: '20px' };
const MyComponent = () => (
<div style={style}>Red text</div>
);
CSS Modules
CSS Modules allow creating local styles for components.
import styles from './MyComponent.module.css';
function MyComponent() {
return <div className={styles.myStyle}>Style with CSS Modules</div>;
}
Styled Components
Allow writing CSS directly in JavaScript using template literals.
import styled from 'styled-components';
const Button = styled.button`
background-color: blue;
color: white;
padding: 10px;
`;
function App() {
return <Button>Click me</Button>;
}
React Router
Installing React Router
For navigation between pages in a SPA (Single Page Application).
npm install react-router-dom
Configuring Routes
import { BrowserRouter as Router, Route, Switch } from 'react-router-dom';
function App() {
return (
<Router>
<Switch>
<Route path="/" exact component={Home} />
<Route path="/about" component={About} />
</Switch>
</Router>
);
}
Programmatic Navigation
To change routes from code.
import { useHistory } from 'react-router-dom';
function MyComponent() {
let history = useHistory();
const navigate = () => {
history.push('/about');
};
return <button onClick={navigate}>Go to About</button>;
}
Fetching and APIs
Fetch
You can use fetch
to get data from a RESTful API.
useEffect(() => {
fetch('https://api.example.com/data')
.then((response) => response.json())
.then((data) => console.log(data));
}, []);
Optimization
Use React.memo
to memoize components and useCallback
to optimize functions.
useMemo
import React, { useMemo } from 'react';
const MyComponent = ({ items }) => {
const calculation = useMemo(() => expensiveCalculation(items), [items]);
return <div>{calculation}</div>;
};
useCallback
import React, { useCallback } from 'react';
const MyComponent = ({ onClick }) => {
const handleClick = useCallback(() => {
onClick();
}, [onClick]);
return <button onClick={handleClick}>Click here</button>;
};