
Create articles from any YouTube video or use our API to get YouTube transcriptions
Start for freeIntroduction to React
React is a JavaScript library for building dynamic and interactive user interfaces. Created by Facebook in 2011, it has become the most widely used front-end development library. React allows developers to create reusable UI components and efficiently update and render them as data changes.
Some key benefits of React include:
- Component-based architecture for modular, reusable code
- Virtual DOM for optimized rendering performance
- Declarative syntax for describing UI state
- Large ecosystem and community support
Setting Up the Development Environment
To get started with React development, you'll need:
- Node.js (version 16 or higher)
- A code editor like Visual Studio Code
- React Developer Tools browser extension
The recommended way to create a new React project is using Vite, a fast build tool. To create a project:
npm create vite@latest react-app -- --template react-ts
cd react-app
npm install
npm run dev
This will set up a new React project with TypeScript support.
React Components
Components are the building blocks of React applications. A component is a reusable piece of UI that can manage its own state and props.
There are two main types of components:
- Function components (recommended)
- Class components (legacy)
Here's an example of a simple function component:
function Greeting(props) {
return <h1>Hello, {props.name}!</h1>;
}
JSX
JSX is a syntax extension for JavaScript that allows you to write HTML-like code in your JavaScript files. It makes it easier to describe the structure of React components.
Example:
const element = <h1>Hello, world!</h1>;
JSX gets compiled to regular JavaScript function calls:
const element = React.createElement('h1', null, 'Hello, world!');
Props
Props (short for properties) are how components receive data from their parent. They are read-only and help make components reusable.
Example:
function Welcome(props) {
return <h1>Welcome, {props.name}</h1>;
}
<Welcome name="Alice" />
State
State represents data that can change over time within a component. When state changes, React re-renders the component.
For function components, we use the useState hook to manage state:
import { useState } from 'react';
function Counter() {
const [count, setCount] = useState(0);
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>
Click me
</button>
</div>
);
}
Handling Events
React events are named using camelCase and passed as functions:
function Button() {
function handleClick() {
alert('Button clicked!');
}
return <button onClick={handleClick}>Click me</button>;
}
Conditional Rendering
You can use JavaScript operators like if or the conditional operator to create elements representing the current state:
function Greeting(props) {
const isLoggedIn = props.isLoggedIn;
return (
<div>
{isLoggedIn ? (
<h1>Welcome back!</h1>
) : (
<h1>Please sign up.</h1>
)}
</div>
);
}
Lists and Keys
When rendering lists in React, it's important to include a unique "key" prop for each item:
function NumberList(props) {
const numbers = props.numbers;
const listItems = numbers.map((number) =>
<li key={number.toString()}>
{number}
</li>
);
return <ul>{listItems}</ul>;
}
Forms
React can control the state of form inputs, making them "controlled components":
function NameForm() {
const [name, setName] = useState('');
function handleSubmit(event) {
alert('A name was submitted: ' + name);
event.preventDefault();
}
return (
<form onSubmit={handleSubmit}>
<label>
Name:
<input type="text" value={name} onChange={(e) => setName(e.target.value)} />
</label>
<input type="submit" value="Submit" />
</form>
);
}
Lifting State Up
When multiple components need to share state, you can lift the state up to their closest common ancestor:
function TemperatureInput(props) {
return (
<fieldset>
<legend>Enter temperature in {props.scale}:</legend>
<input
value={props.temperature}
onChange={(e) => props.onTemperatureChange(e.target.value)} />
</fieldset>
);
}
function Calculator() {
const [temperature, setTemperature] = useState('');
const [scale, setScale] = useState('c');
function handleCelsiusChange(temperature) {
setScale('c');
setTemperature(temperature);
}
function handleFahrenheitChange(temperature) {
setScale('f');
setTemperature(temperature);
}
const celsius = scale === 'f' ? tryConvert(temperature, toCelsius) : temperature;
const fahrenheit = scale === 'c' ? tryConvert(temperature, toFahrenheit) : temperature;
return (
<div>
<TemperatureInput
scale="c"
temperature={celsius}
onTemperatureChange={handleCelsiusChange} />
<TemperatureInput
scale="f"
temperature={fahrenheit}
onTemperatureChange={handleFahrenheitChange} />
</div>
);
}
Composition vs Inheritance
React has a powerful composition model, and it's recommended to use composition instead of inheritance to reuse code between components:
function FancyBorder(props) {
return (
<div className={'FancyBorder FancyBorder-' + props.color}>
{props.children}
</div>
);
}
function WelcomeDialog() {
return (
<FancyBorder color="blue">
<h1 className="Dialog-title">
Welcome
</h1>
<p className="Dialog-message">
Thank you for visiting our spacecraft!
</p>
</FancyBorder>
);
}
Hooks
Hooks are functions that let you "hook into" React state and lifecycle features from function components. Some common hooks include:
- useState: Adds state to function components
- useEffect: Performs side effects in function components
- useContext: Subscribes to React context without introducing nesting
- useReducer: Manages complex state logic
- useCallback: Returns a memoized callback function
- useMemo: Returns a memoized value
Example using useEffect:
import { useState, useEffect } from 'react';
function Example() {
const [count, setCount] = useState(0);
useEffect(() => {
document.title = `You clicked ${count} times`;
});
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>
Click me
</button>
</div>
);
}
Context
Context provides a way to pass data through the component tree without having to pass props down manually at every level:
const ThemeContext = React.createContext('light');
function App() {
return (
<ThemeContext.Provider value="dark">
<Toolbar />
</ThemeContext.Provider>
);
}
function Toolbar() {
return (
<div>
<ThemedButton />
</div>
);
}
function ThemedButton() {
const theme = useContext(ThemeContext);
return <Button theme={theme} />;
}
Error Boundaries
Error boundaries are React components that catch JavaScript errors anywhere in their child component tree, log those errors, and display a fallback UI:
class ErrorBoundary extends React.Component {
constructor(props) {
super(props);
this.state = { hasError: false };
}
static getDerivedStateFromError(error) {
return { hasError: true };
}
componentDidCatch(error, errorInfo) {
logErrorToMyService(error, errorInfo);
}
render() {
if (this.state.hasError) {
return <h1>Something went wrong.</h1>;
}
return this.props.children;
}
}
Code-Splitting
Code-splitting your app can help you "lazy-load" just the things that are currently needed by the user, which can dramatically improve the performance of your app:
import { lazy, Suspense } from 'react';
const OtherComponent = lazy(() => import('./OtherComponent'));
function MyComponent() {
return (
<div>
<Suspense fallback={<div>Loading...</div>}>
<OtherComponent />
</Suspense>
</div>
);
}
Performance Optimization
React provides several ways to optimize performance:
- Use the Production Build
- Virtualize Long Lists
- Avoid Reconciliation with shouldComponentUpdate, PureComponent, or React.memo
- Use Immutable Data Structures
- Lazy Loading Components
Example using React.memo:
const MyComponent = React.memo(function MyComponent(props) {
/* render using props */
});
Testing
Testing React components typically involves rendering components, simulating user interactions, and asserting on the output. Popular testing libraries include Jest and React Testing Library.
Example test:
import { render, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import Counter from './Counter';
test('increments counter', () => {
render(<Counter />);
const button = screen.getByText('Increment');
userEvent.click(button);
expect(screen.getByText('Count: 1')).toBeInTheDocument();
});
Conclusion
React is a powerful library for building user interfaces. Its component-based architecture, virtual DOM, and rich ecosystem make it an excellent choice for modern web development. By mastering the concepts covered in this article, you'll be well on your way to building fast, scalable, and maintainable React applications.
Remember to practice regularly, explore the React documentation, and stay updated with the latest features and best practices in the React community. Happy coding!
Article created from: https://www.youtube.com/watch?v=SqcY0GlETPk&t=163s