React Reference API
This documentation covers the essential concepts and components of the React Reference API, including components, JSX, props, state, context, hooks, forms, state management, composition vs inheritance, HOCs, render props, context API and Redux, refs, error boundaries, fragments, portals, profiler, server rendering, strict mode, concurrent mode, transitions, suspense, integrating with other libraries, advanced rendering techniques, optimizing performance, accessible forms, accessibility in React, debugging, security, tools and resources, and a detailed API reference.
Introduction to React Reference API
React is a powerful library for building user interfaces, particularly single-page applications where you need a fast, responsive UI. The React Reference API is a collection of functions, properties, and concepts that provide the core building blocks for React applications. Understanding the React Reference API is crucial for effectively using React and building robust applications.
What is the React Reference API?
The React Reference API is essentially a documentation guide that provides developers with the methods, hooks, and components available in React. It includes detailed explanations, examples, and usage guidelines for each part of the library.
Purpose of the React Reference API
The React Reference API serves as the official handbook for all React developers. It helps in learning how to use React's features effectively and efficiently by providing clear documentation, practical examples, and best practices.
React Components
Components are the building blocks of any React application. They allow you to split your UI into independent, reusable pieces and think about each piece in isolation.
Function Components
Function components are the simplest way to create components in React. They are JavaScript functions that return JSX.
function Welcome(props) {
return <h1>Hello, {props.name}</h1>;
}
In this example, the Welcome
function is a functional component. It accepts a props
object that contains the properties passed to the component and returns a React element describing what should appear on the screen.
Class Components
Class components are more feature-rich than function components but can be more complex to write due to the additional boilerplate code.
class Welcome extends React.Component {
render() {
return <h1>Hello, {this.props.name}</h1>;
}
}
In this snippet, the Welcome
class extends React.Component
and defines a render
method that returns a React element.
Lifecycle Methods
Class components can have lifecycle methods that get called during different phases of their existence, such as mounting, updating, and unmounting the component.
Mounting
These methods are called when the component is being inserted into the DOM.
constructor()
: A special method for creating and initializing an object.render()
: Required method. Examines this.props and this.state and returns a React element.componentDidMount()
: Invoked immediately after a component is mounted.
Updating
These are called when a component is being re-rendered as a result of changes to either its props or state.
shouldComponentUpdate()
: Determines if the component should re-render when new props or state are received.render()
: Invoked when a component needs to be re-rendered.componentDidUpdate()
: Invoked immediately after updating occurs. Not called for the initial render.
Unmounting
This is called when a component is being removed from the DOM.
componentWillUnmount()
: Cleanup method that allows you to perform necessary cleanup right before the component is unmounted from the DOM.
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 instead of the component tree that crashed.
class ErrorBoundary extends React.Component {
constructor(props) {
super(props);
this.state = { hasError: false };
}
static getDerivedStateFromError(error) {
return { hasError: true };
}
componentDidCatch(error, errorInfo) {
console.error("Caught an error", error, errorInfo);
}
render() {
if (this.state.hasError) {
return <h1>Something went wrong.</h1>;
}
return this.props.children;
}
}
This ErrorBoundary
class component will catch any errors in its child components and display "Something went wrong." if an error occurs.
JSX
JSX stands for JavaScript XML. It's a syntax extension for JavaScript that looks similar to HTML, and it helps you write JSX tags, which are then transformed into function calls.
What is JSX?
JSX provides an elegant syntax to write elements that describe how the UI should look. It is not required to use React, but JSX makes it easier to write and understand what your React components look like.
Writing JSX
JSX is syntactic sugar for function calls to React.createElement(component, props, ...children)
.
const element = (
<h1 className="greeting">
Hello, world!
</h1>
);
This JSX code is syntactic sugar for the following:
const element = React.createElement(
'h1',
{className: 'greeting'},
'Hello, world!'
);
Embedding Expressions
You can embed any JavaScript expression inside curly braces in JSX.
const name = 'Josh Perez';
const element = <h1>Hello, {name}</h1>;
In this example, the JavaScript variable name
is embedded inside the JSX using curly braces, resulting in the element displaying "Hello, Josh Perez".
Specifying Attributes
You may use quotes to specify string literals as attributes.
const element = <div tabIndex="0"></div>;
You may also use curly braces to embed a JavaScript expression in an attribute.
const element = <img src={user.avatarUrl}></img>;
In this example, the src
attribute of the img
element is set using a JavaScript expression embedded in curly braces.
Specifying Children
If a tag is empty, you may close it immediately with />
, just like XML.
const element = <img src={user.avatarUrl} />;
JSX tags can contain children.
const element = (
<div>
<h1>Hello!</h1>
<h2>Good to see you here.</h2>
</div>
);
Preventing Injection Attacks
React DOM escapes any values embedded in JSX before rendering them. This helps prevent XSS (cross-site scripting) attacks by sanitizing the input data.
const title = response.potentiallyMaliciousInput;
// This is safe:
const element = <h1>{title}</h1>;
In this example, response.potentiallyMaliciousInput
is sanitized before being rendered inside the h1
tag.
Props
Props are read-only in React. This means that a component can only read the props passed to it and cannot modify them.
What are Props?
Props are short for properties. They are the arguments passed into React components to customize and manipulate their behavior.
Passing Props
function Welcome(props) {
return <h1>Hello, {props.name}</h1>;
}
const element = <Welcome name="Sara" />;
In this example, the Welcome
component is passed a name
prop with the value "Sara". The component reads the value of the name
prop and returns a React element displaying "Hello, Sara".
Default Props
Default props can be defined for a component.
class Greeting extends React.Component {
render() {
return <h1>Hello, {this.props.name}</h1>;
}
}
Greeting.defaultProps = {
name: 'Stranger'
};
In this example, if no name
prop is passed to the Greeting
component, it will default to "Stranger".
PropTypes
PropTypes is a library that helps type-checking the props passed to components.
import PropTypes from 'prop-types';
class Greeting extends React.Component {
render() {
return <h1>Hello, {this.props.name}</h1>;
}
}
Greeting.propTypes = {
name: PropTypes.string
};
In this example, PropTypes.string
ensures that the name
prop must be a string. If name
is not a string, a warning will be shown in the JavaScript console.
State
State is a feature in React that enables components to store data and re-render when the data changes.
What is State?
State is an object that holds the data that needs to be shared and changed between the various functions of a React component.
Adding Local State to a Class
You can add local state to a class by declaring a state
property in the constructor of the class.
class Clock extends React.Component {
constructor(props) {
super(props);
this.state = {date: new Date()};
}
render() {
return (
<div>
<h1>Hello, world!</h1>
<h2>It is {this.state.date.toLocaleTimeString()}.</h2>
</div>
);
}
}
In this example, the Clock
class component initializes its state in its constructor with a date
property. The render
method then accesses the state value using this.state.date
and displays the current time.
State Updates Are Merged
When you want to update the state, you should not modify the state directly.
this.setState({comment: 'Hello'});
In this example, setState
is used to update the comment
property of the state object.
State Updates May Be Asynchronous
React may batch multiple setState()
calls into a single update for performance reasons.
this.setState({quantity: this.state.quantity + 1});
For code that relies on previous state, such as an increment counter, use the function form of setState
.
this.setState((state, props) => ({
counter: state.counter + props.increment
}));
In this example, the function form of setState
ensures that the increment operation is based on the previous state.
Using Functional State Updates
When state updates should be based on the previous state, use a function to perform the update instead of using an object.
this.setState((prevState) => ({
count: prevState.count + 1
}));
In this example, the count
property of the state object is incremented by 1 based on the previous state.
Context
Context provides a way to pass data through the component tree without having to pass props down manually at every level.
What is Context?
Context allows you to define a value that is accessible to all components in the tree, without having to pass props explicitly.
When to Use Context?
Context is useful when some data needs to be accessible by many components at different nesting levels. Examples include:
- Authentication status
- Theme (light/dark)
- Location settings
Before You Use Context
Before using context, consider other simpler solutions, such as lifting state up or component composition.
API
React.createContext
Creates a Context object. When React renders a context provider, it reads the nearest current value of that context from the closest matching Provider
above and uses it to render the children.
const MyContext = React.createContext(defaultValue);
In this example, React.createContext
creates a Context object with a default value.
Context.Provider
A Provider component that accepts a value prop to be passed to consuming components that are descendants of this Provider.
<MyContext.Provider value={someValue}>
<ChildComponent />
</MyContext.Provider>
In this code snippet, the MyContext.Provider
component provides the someValue
to all descendants of the ChildComponent
.
Context.Consumer
A Consumer component that subscribes to context changes. This lets you subscribe to context within a function component.
class MyClass extends React.Component {
render() {
return (
<MyContext.Consumer>
{value => /* render something based on the context value */}
</MyContext.Consumer>
);
}
}
In this example, the MyContext.Consumer
subscribes to MyContext
and renders something based on the context value.
Context.displayName
Sets the display name for debugging contexts using React DevTools.
const MyContext = React.createContext(/* some value */);
MyContext.displayName = 'MyDisplayName';
In this snippet, MyContext
is given a display name of MyDisplayName
for debugging purposes.
Hooks
Hooks allow you to use state and other React features without writing a class.
Introduction to Hooks
Hooks let you use state and other React features without writing a class.
State Hook
Declaring a State Variable
You can use the useState
hook to add state to function components.
import React, { useState } from 'react';
function Example() {
// Declare a new state variable, which we'll call "count"
const [count, setCount] = useState(0);
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>
Click me
</button>
</div>
);
}
In this example, useState
initializes the count
state variable to 0.
Reading State
States can be used in JSX as if they were regular variables.
function Example() {
const [count, setCount] = useState(0);
return <p>You clicked {count} times</p>;
}
In this code, count
is used as a regular variable inside JSX to display the count.
Updating State
You can use the set function returned by useState
to update the state.
function Example() {
const [count, setCount] = useState(0);
return (
<button onClick={() => setCount(count + 1)}>
Click me
</button>
);
}
In this example, setCount
is used to update the count
state variable when the button is clicked.
Effect Hook
Side Effects Without Hooks
In class components, side effects are typically performed in componentDidMount
, componentDidUpdate
, and componentWillUnmount
. These lifecycle methods perform side effects, and it's easy to forget to handle all cases.
Effect Hook Explanation
The Effect Hook lets you perform side effects in function components.
import React, { useEffect } from 'react';
function Example() {
useEffect(() => {
// This effect runs after every render, including the first one
document.title = `You clicked ${count} times`;
});
return <p>You clicked {count} times</p>;
}
In this example, the useEffect
hook updates the document title after every render, including the first one.
Tips for Using Effects
Optimizing Performance by Skipping Effects
You can tell React to skip applying an effect if certain values haven't changed.
useEffect(() => {
document.title = `You clicked ${count} times`;
}, [count]); // Only re-run the effect if count changes
In this code, the effect will only re-run if the count
value changes.
Rules of Hooks
Only Call Hooks at the Top Level
Don't call Hooks inside loops, conditions, or nested functions. Instead, always use Hooks at the top level of your React function.
Only Call Hooks from React Functions
Don't call Hooks from regular JavaScript functions. Instead, call Hooks from React function components or custom Hooks.
Forms
Forms in React are a bit different from other DOM elements because form elements in HTML maintain their own state that is mutable.
Controlled Components
A controlled component is one whose value is controlled by React state. To make a form element a controlled component, you need to do two things:
- Control the component's state.
- Pass a callback function to update the state.
Input Tags
textarea Tag
Use the value
attribute to set the contents of a textarea
.
<textarea value={this.state.value} onChange={this.handleChange} />
In this example, the textarea
content is controlled by the value
attribute, which is tied to the state.
select Tag
You can create a select
item by using the value
attribute.
<select value={this.state.value} onChange={this.handleChange}>
<option value="grapefruit">Grapefruit</option>
<option value="lime">Lime</option>
<option selected value="coconut">Coconut</option>
<option value="mango">Mango</option>
</select>
In this example, the select
item is controlled by the value
attribute, which is tied to the state.
Handling Multiple Inputs
Control multiple inputs by adding a name
attribute to each input
and letting the handler function determine which state property to update.
class Reservation extends React.Component {
state = {
isGoing: true,
numberOfGuests: 2
};
handleChange = (event) => {
const target = event.target;
const value = target.type === 'checkbox' ? target.checked : target.value;
const name = target.name;
this.setState({
[name]: value
});
};
render() {
return (
<form>
<label>
Is going:
<input
name="isGoing"
type="checkbox"
checked={this.state.isGoing}
onChange={this.handleChange} />
</label>
<br />
<label>
Number of guests:
<input
name="numberOfGuests"
type="number"
value={this.state.numberOfGuests}
onChange={this.handleChange} />
</label>
</form>
);
}
}
In this example, the handleChange
method updates the appropriate state field based on the name
attribute of the input elements.
Controlled Input Null Value
Specifying a value for the controlled input will prevent the user from changing the input unless you intend to.
render() {
return (
<input value={this.state.value} onChange={this.handleChange} />
);
}
In this example, the value
attribute is set to this.state.value
, making the input controlled.
State Management
Lifting State Up
Sometimes, you need the state of several components to reflect the same data. It is recommended to lift the shared state up to their closest common ancestor.
Thinking in React
- Break the UI into a component hierarchy.
- Build a static version in React.
- Identify the minimal (but complete) representation of UI state.
- Identify where the state should live.
- Add inverse data flow.
Composition vs Inheritance
Containment
Containment is a design pattern where there is no need to know the children of a component in advance.
function FancyBorder(props) {
return (
<div className={'FancyBorder FancyBorder-' + props.color}>
{props.children}
</div>
);
}
In this example, FancyBorder
uses {props.children}
to render anything inside the child component(s).
Specialization
Specialization is a concept where a more specialized component is a special case of a more generic one.
function Dialog(props) {
return (
<FancyBorder color="blue">
<h1 className="Dialog-title">
{props.title}
</h1>
<p className="Dialog-message">
{props.message}
</p>
</FancyBorder>
);
}
In this example, the Dialog
component is a specialization of the FancyBorder
component, passing additional props like title
and message
.
Higher-Order Components (HOCs)
A higher order component is a function that takes a component and returns a new component.
Use HOCs for Cross-Cutting Concerns
HOCs are used to share common functionality between components.
Caveats
Don’t Use HOCs Inside the Render Method
Using HOCs inside the render
method will cause the component to unmount on every update.
Static Methods Must Be Copied Over
Static methods must be copied onto the container component when you use HOCs.
Refs Aren’t Passed Through
Refs do not get passed through. Higher-order components (HOCs) imperatively modify the component to add extra behavior. However, another common use case for refs is to access the underlying DOM element or the inner component instance.
Conventional Props
render props
The render prop is a technique for sharing code between React components using a propagation pattern where you pass a function as a prop to a component that calls that function instead of implementing render logic itself.
props.children
The most common way for components to render children in their output is via the special children
prop.
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>
);
}
In this example, WelcomeDialog
passes its children to FancyBorder
through props.children
.
Render Props
Using Props to Pass a Render Function
class Cat extends React.Component {
render() {
return <h1>{this.props.render(this.props.cat)}</h1>;
}
}
class Mouse extends React.Component {
constructor(props) {
super(props);
this.state = { x: 0, y: 0 };
}
handleMouseMove = (event) => {
this.setState({
x: event.clientX,
y: event.clientY
});
}
render() {
return (
<div style={{ height: '100vh' }} onMouseMove={this.handleMouseMove}>
{/*
Instead of providing a static representation of what <MouseWithCat>
renders, we provide a function that knows about both render props
and the render prop.
*/}
{this.props.render(this.state)}
</div>
);
}
}
function App() {
return (
<div>
<h1>Move the mouse around!</h1>
<Mouse render={
mouse => <Cat mouse={mouse} />
}/>
</div>
);
}
In this example, the Mouse
component uses the render
prop to pass mouse
state to the Cat
component.
Using Render Props for Cross-Cutting Concerns
Render props can also be used for cross-cutting concerns like user authentication, window dimensions, etc.
Caveats
Be Careful When Using Render Props with React.PureComponent
If you are using the render
prop and the PureComponent
class, it might not work as expected.
Context API and Redux
Context API
Creating Context
const MyContext = React.createContext(defaultValue);
In this example, a new context object MyContext
is created with a default value.
Context.Provider
<MyContext.Provider value={someValue}>
<ChildComponent />
</MyContext.Provider>
In this snippet, someValue
is passed down to the child components.
Context.Consumer
<MyContext.Consumer>
{value => /* render something based on the value */}
</MyContext.Consumer>
In this example, the Context.Consumer
subscribes to MyContext
and renders something based on the context value.
Context.displayName
const MyContext = React.createContext(defaultValue);
MyContext.displayName = 'MyDisplayName';
In this example, MyContext
is given a display name of MyDisplayName
.
React Refs
Creating Refs
class MyComponent extends React.Component {
constructor(props) {
super(props);
this.myRef = React.createRef();
}
render() {
return <div ref={this.myRef} />;
}
}
In this example, this.myRef
is created in the constructor and attached to a div
in the render method.
Accessing Refs
You can access the current property of the ref to get the actual DOM node or React element.
class MyComponent extends React.Component {
myRef = React.createRef();
componentDidMount() {
// Access the DOM node
console.log(this.myRef.current);
}
render() {
return <div ref={this.myRef} />;
}
}
In this snippet, this.myRef.current
is used to access the DOM node after the component is mounted.
Adding a Ref to a Class Component
class CustomTextInput extends React.Component {
constructor(props) {
super(props);
// Create a ref to store the textInput DOM element
this.textInput = React.createRef();
}
focusTextInput = () => {
// Explicitly focus the text input using the raw DOM API
this.textInput.current.focus();
}
render() {
// Use the `ref` callback attribute to store a reference to the text input DOM element
return (
<div>
<input
type="text"
ref={this.textInput} />
<input
type="button"
value="Focus the text input"
onClick={this.focusTextInput}
/>
</div>
);
}
}
In this example, the TextInput
is focused via the ref when the button is clicked.
Callback Refs
class CustomTextInput extends React.Component {
constructor(props) {
super(props);
this.textInput = null;
this.setTextInputRef = element => {
this.textInput = element;
};
}
focusTextInput = () => {
if (this.textInput) this.textInput.focus();
// Explicitly focus the text input using the raw DOM API
}
render() {
return (
<div>
<input
type="text"
ref={this.setTextInputRef} />
<input
type="button"
value="Focus the text input"
onClick={this.focusTextInput}
/>
</div>
);
}
}
In this example, a callback ref is used to set the textInput
property of the component to the DOM node when it mounts.
Forwarding Refs
function FancyButton(props) {
return (
<button className="FancyButton">
{props.children}
</button>
);
}
In this example, a standard button component is created.
Forwarding Refs in Higher Order Components
function logProps(WrappedComponent) {
class LogProps extends React.Component {
componentDidUpdate(prevProps) {
console.log('old props:', prevProps);
console.log('new props: ', this.props);
}
render() {
// Wraps the input component in a div with a friendly display name.
return <WrappedComponent {...this.props} />;
}
}
return LogProps;
}
In this snippet, a higher-order component that logs props changes is created.
Error Boundaries
Catching Errors with Error Boundaries
class ErrorBoundary extends React.Component {
constructor(props) {
super(props);
this.state = { hasError: false };
}
static getDerivedStateFromError(error) {
// Update state so the next render will show the fallback UI.
return { hasError: true };
}
componentDidCatch(error, errorInfo) {
// You can also log the error to an error reporting service
logErrorToMyService(error, errorInfo);
}
render() {
if (this.state.hasError) {
// You can render any custom fallback UI
return <h1>Something went wrong.</h1>;
}
return this.props.children;
}
}
<ErrorBoundary>
<MyWidget />
</ErrorBoundary>
In this example, an ErrorBoundary
reacts to errors when rendering, in lifecycle methods, or in the constructors of any of its children.
How Error Boundaries Work
Error boundaries catch JavaScript errors anywhere in their child component tree, log those errors, and display a fallback UI instead of crashing the whole component tree.
Where to Place Error Boundaries
Consider where in your component tree should have error boundaries. Error boundaries work like catch in JavaScript — they catch errors that happen anywhere in their child component tree, not in themselves.
New Lifecycle Methods
static getDerivedStateFromError(error)
componentDidCatch(error, info)
Fragments
Why Fragments Are Useful
You can return a single element in a component’s render method. However, sometimes you want to group a list of children without adding extra nodes to the DOM.
Keyed Fragments
function ItemList(props) {
return (
<React.Fragment>
{props.items.map(item => (
// Without the `key`, React will give a key warning
<li key={item.id}>{item.text}</li>
))}
</React.Fragment>
);
}
In this example, React.Fragment
is used to wrap the list items without adding an additional DOM node.
Creating Fragments
function Table() {
return (
<table>
<tr>
<Column />
</tr>
</table>
);
}
function Column() {
return (
<React.Fragment>
<td>Hello</td>
<td>World</td>
</React.Fragment>
);
}
In this code snippet, React.Fragment
is used to group multiple td
elements without adding an additional DOM node.
Portals
What Are Portals?
Portals provide a way to render children into a DOM node that exists outside the DOM hierarchy of the parent component.
How to Use Portals
const portalRoot = document.getElementById('portal-root');
class Modal extends React.Component {
componentDidMount() {
this.mountNode = document.createElement('div');
portalRoot.appendChild(this.mountNode);
}
componentWillUnmount() {
portalRoot.removeChild(this.mountNode);
}
render() {
return ReactDOM.createPortal(
this.props.children,
this.mountNode
);
}
}
In this example, the Modal
component uses ReactDOM.createPortal
to render its children into a div
with the id portal-root
.
Profiler
Purpose of Profiler
Profiler is a component that measures the performance of rendering in a subtree. It helps in identifying performance issues in the component that slow down the app.
onRender Callback
The onRender
prop is a callback for when a component renders. It is fired after the component tree has committed an update.
<Profiler id="panel" onRender={callback}>
<Panel />
</Profiler>
In this example, the callback
function is called when the Panel
component renders.
Profiler Nesting
<Profiler id="Outer">
<div>
<Profiler id="Inner">
<p>Hello World</p>
</Profiler>
</div>
</Profiler>
In this example, the Profiler
components are nested, allowing you to measure performance at different levels of the component hierarchy.
Server Rendering
Server Rendering with Data Requirements
Server-side rendering can boost your app's performance by rendering components on the server and sending the HTML early.
Data Fetching
You can fetch data in the server and pass it to your React components as props.
Strict Mode
Enabling Strict Mode
<StrictMode>
<App />
</StrictMode>
In this snippet, the App
component is wrapped in StrictMode
, enabling the strict mode in the entire app.
Strict Mode’s Behavior
- Identifies components with unsafe lifecycle methods.
- Warns about legacy string ref API usage.
- Warns about deprecated findDOMNode() usage.
Concurrent Mode
Introduction to Concurrent Mode
Concurrent Mode is a set of features that allow React apps to render updates to the user interface in a more flexible way with more granular control.
Why Concurrent Mode?
- Enables React to interrupt and resume rendering tasks when it detects high-priority updates.
- Includes features like Suspense and Transitions.
Transitions
What is a Transition?
Transitions are a feature in Concurrent Mode that allows components to opt out of participating in a concurrent render and be updated as a group after a high-priority interaction has completed.
Start a Transition
import { startTransition } from 'react';
startTransition(() => {
someAction();
});
In this example, the someAction
function is wrapped a startTransition
, allowing it to participate in a transition.
Updating the UI During a Transition
You can use the isPending
hook to track transitions.
import { useTransition } from 'react';
function TransitionComponent({ isPending }) {
return isPending ? <LoadingSpinner /> : <MainContent />;
}
In this example, a LoadingSpinner
is shown if the transition is pending, otherwise MainContent
is shown.
Understanding the Animation
React.memo and useCallback are used to optimize performance during transitions.
React.memo
const Button = React.memo(function Button({ value, onClick }) {
return <button onClick={onClick}>{value}</button>;
});
In this example, React.memo
is used to prevent unnecessary re-renders of the Button
component.
useCallback
const memoizedValue = useCallback(
() => {
doSomething(a, b);
},
[a, b]
);
In this example, useCallback
is used to memoize a callback function.
useDeferredValue
const deferredValue = useDeferredValue(someValue);
In this example, useDeferredValue
wraps a value and returns a new value that will be the previous one until the concurrent render has completed.
Examples of useDeferredValue
const deferredValue = useDeferredValue(value);
function List() {
// The deferred value will update later, allowing the text field to update immediately.
return <ExpensiveList items={deferredValue} />;
}
In this example, useDeferredValue
is used to defer the update of items
in the List
component while the text field is updated immediately.
Suspense
Suspense for Code Splitting
const OtherComponent = React.lazy(() => import('./OtherComponent'));
function MyComponent() {
return (
<div>
<Suspense fallback={<div>Loading...</div>}>
<OtherComponent />
</Suspense>
</div>
);
}
In this example, OtherComponent
is lazily loaded and a fallback UI is displayed while it is being loaded.
Using Suspense for Data Fetching
function ProfilePage() {
const user = useProfileData(userID);
return (
<Suspense fallback={<Spinner />}>
<ProfileDetails user={user} />
</Suspense>
);
}
In this example, the user data is fetched asynchronously, and a Spinner
is shown during the loading state.
Revealing Nested Suspense
const MainLayout = () => (
<div>
<Header />
<Suspense fallback={<LoadingSpinner />}>
<section>
<Suspense fallback={<LoadingBar />}>
<ProfileComponent />
</Suspense>
<Suspense fallback={<LoadingBar />}>
<PhotosComponent />
</Suspense>
</section>
</Suspense>
<Footer />
</div>
);
function ProfileComponent() {
const user = useProfileData(userID);
return <h1>{user.name}</h1>;
}
In this example, nested Suspense
components are used to reveal different parts of the UI at different times.
React Refs
Creating Refs
class MyComponent extends React.Component {
constructor(props) {
super(props);
this.myRef = React.createRef();
}
render() {
return <div ref={this.myRef} />;
}
}
In this example, a ref is created in the constructor and attached to a div
in the render
method.
Accessing Refs
class MyComponent extends React.Component {
constructor(props) {
super(props);
this.myRef = React.createRef();
}
componentDidMount() {
// Access the DOM node
console.log(this.myRef.current);
}
render() {
return <div ref={this.myRef} />;
}
}
In this snippet, the this.myRef.current
is used to access the DOM node after the component is mounted.
Adding a Ref to a Class Component
class CustomTextInput extends React.Component {
constructor(props) {
super(props);
this.textInput = React.createRef();
}
focusTextInput = () => {
if (this.textInput.current) this.textInput.current.focus();
}
render() {
return (
<div>
<input
type="text"
ref={this.textInput} />
<input
type="button"
value="Focus the text input"
onClick={this.focusTextInput}
/>
</div>
);
}
}
In this example, a ref is used to focus the text input when the button is clicked.
Callback Refs
class CustomTextInput extends React.Component {
constructor(props) {
super(props);
this.textInput = null;
this.setTextInputRef = element => {
this.textInput = element;
};
}
focusTextInput = () => {
if (this.textInput) this.textInput.focus();
}
render() {
return (
<div>
<input
type="text"
ref={this.setTextInputRef} />
<input
type="button"
value="Focus the text input"
onClick={this.focusTextInput}
/>
</div>
);
}
}
In this example, a callback ref is used to set the textInput
property of the component to the DOM node when it mounts.
Forwarding Refs
const FancyButton = React.forwardRef((props, ref) => (
<button ref={ref} className="FancyButton">
{props.children}
</button>
));
In this code snippet, the FancyButton
component forwards its ref
to the underlying button
element.
Forwarding Refs in Higher Order Components
function logProps(WrappedComponent) {
class LogProps extends React.Component {
componentDidUpdate(prevProps) {
console.log('old props:', prevProps);
console.log('new props: ', this.props);
}
render() {
return <WrappedComponent {...this.props} />;
}
}
return LogProps;
}
In this example, the logProps
HOC logs when its wrapped component's props change.
Fragments
Why Fragments Are Useful
Fragments are useful for grouping elements without adding extra DOM elements.
Keyed Fragments
function ItemList(props) {
return (
<React.Fragment>
{props.items.map(item => (
// Without the `key`, React will give a key warning
<li key={item.id}>{item.text}</li>
))}
</React.Fragment>
);
}
In this example, React.Fragment
is used to wrap the list items without adding an additional DOM node.
Creating Fragments
function Table() {
return (
<table>
<tr>
<Column />
</tr>
</table>
);
}
function Column() {
return (
<React.Fragment>
<td>Hello</td>
<td>World</td>
</React.Fragment>
);
}
In this example, React.Fragment
is used to group the td
elements without adding an additional DOM node.
Portals
What Are Portals?
Portals provide a way to render children into a DOM node that exists outside the DOM hierarchy of the parent component.
How to Use Portals
const portalRoot = document.getElementById('portal-root');
class Modal extends React.Component {
componentDidMount() {
this.mountNode = document.createElement('div');
portalRoot.appendChild(this.mountNode);
}
componentWillUnmount() {
portalRoot.removeChild(this.mountNode);
}
render() {
return ReactDOM.createPortal(
this.props.children,
this.mountNode
);
}
}
In this example, the Modal
component uses ReactDOM.createPortal
to render its children into a div
with the id portal-root
.
Profiler
Purpose of Profiler
The Profiler measures the performance of rendering in a subtree. It helps in identifying performance issues in the component that slow down the app.
onRender Callback
The onRender
prop is a callback for when a component renders.
<Profiler id="navigation" onRender={callback}>
<Navigation />
</Profiler>
In this example, the callback
function is called when the Navigation
component renders.
Profiler Nesting
<Profiler id="panel">
<div>
<Profiler id="inner">
<p>Hello</p>
</Profiler>
<Profiler id="button">
<button>Click me</button>
</Profiler>
</div>
</Profiler>
In this example, Profiler
components are nested, allowing you to measure performance at different levels of the component hierarchy.
Server Rendering
Server Rendering with Data Requirements
Server-side rendering can boost your app's performance by rendering components on the server and sending the HTML early.
Data Fetching
You can fetch data in the server and pass it to your React components as props.
Strict Mode
Enabling Strict Mode
<StrictMode>
<App />
</StrictMode>
In this code snippet, the App
component is wrapped in StrictMode
, enabling the strict mode in the entire app.
Strict Mode’s Behavior
- Identifies components with unsafe lifecycle methods.
- Warns about legacy string ref API usage.
- Warns about deprecated findDOMNode() usage.
Concurrent Mode
Introduction to Concurrent Mode
Concurrent Mode is a set of features that allow React apps to render updates to the user interface in a more flexible way with more granular control.
Why Concurrent Mode?
- Enables React to interrupt and resume rendering tasks when it detects high-priority updates.
- Includes features like Suspense and Transitions.
Transitions
What is a Transition?
Transitions are a feature in Concurrent Mode that allows components to opt out of participating in a concurrent render and be updated as a group after a high-priority interaction has completed.
Start a Transition
import { startTransition } from 'react';
startTransition(() => {
someAction();
});
In this example, the someAction
function is wrapped a startTransition
, allowing it to participate in a transition.
Updating the UI During a Transition
You can use the isPending
hook to track transitions.
import { useTransition } from 'react';
const deferredValue = useDeferredValue(value);
function List() {
// The deferred value will update later, allowing the text field to update immediately.
return <ExpensiveList items={deferredValue} />;
}
In this example, useDeferredValue
wraps a value and returns a new value that will be the previous one until the concurrent render has completed.
Understanding the Animation
React.memo and useCallback are used to optimize performance during transitions.
React.memo
const Button = React.memo(function Button({ value, onClick }) {
return <button onClick={onClick}>{value}</button>;
});
In this example, React.memo
is used to prevent unnecessary re-renders of the Button
component.
useCallback
const memoizedValue = useCallback(
() => {
doSomething(a, b);
},
[a, b]
);
In this example, useCallback
is used to memoize a callback function.
useDeferredValue
const deferredValue = useDeferredValue(someValue);
In this example, useDeferredValue
wraps a value and returns a new value that will be the previous one until the concurrent render has completed.
Examples of useDeferredValue
const deferredValue = useDeferredValue(value);
function List() {
// The deferred value will update later, allowing the text field to update immediately.
return <ExpensiveList items={deferredValue} />;
}
In this example, useDeferredValue
is used to defer the update of items
in the List
component while the text field is updated immediately.
Suspense
Suspense for Code Splitting
const OtherComponent = React.lazy(() => import('./OtherComponent'));
function MyComponent() {
return (
<div>
<Suspense fallback={<div>Loading...</div>}>
<OtherComponent />
</Suspense>
</div>
);
}
In this example, OtherComponent
is lazily loaded, and a fallback UI is displayed while it is being loaded.
Using Suspense for Data Fetching
function ProfilePage() {
const user = useProfileData(userID);
return (
<Suspense fallback={<Spinner />}>
<ProfileDetails user={user} />
</Suspense>
);
}
In this example, the user data is fetched asynchronously, and a Spinner
is shown during the loading state.
Revealing Nested Suspense
const MainLayout = () => (
<div>
<Header />
<Suspense fallback={<LoadingSpinner />}>
<section>
<Suspense fallback={<LoadingBar />}>
<ProfileComponent />
</Suspense>
<Suspense fallback={<LoadingBar />}>
<PhotosComponent />
</Suspense>
</section>
</Suspense>
<Footer />
</div>
);
function ProfileComponent() {
const user = useProfileData(userID);
return <h1>{user.name}</h1>;
}
In this example, nested Suspense
components are used to reveal different parts of the UI at different times.
Integrating with Other Libraries
Writing Reusable Components with Props and Compose
Higher-Order Components and Render Props
Higher-order components (HOCs) and render props are powerful patterns for code reuse in React. They help in abstracting logic from components.
const EnhancedComponent = withLogging(MyComponent);
In this example, the withLogging
HOC is used to add logging to MyComponent
.
Advanced Rendering Techniques
React.lazy
const OtherComponent = React.lazy(() => import('./OtherComponent'));
function MyComponent() {
return <OtherComponent />;
}
In this example, OtherComponent
is lazily loaded.
React.Suspense
function MyComponent() {
return (
<Suspense fallback={<div>Loading...</div>}>
<OtherComponent />
</Suspense>
);
}
In this snippet, the MyComponent
component uses Suspense
to display a loading message while OtherComponent
is being loaded lazily.
Code Splitting with React.lazy
const OtherComponent = React.lazy(() => import('./OtherComponent'));
function MyComponent() {
return (
<div>
<Suspense fallback={<div>Loading...</div>}>
<OtherComponent />
</Suspense>
</div>
);
}
In this example, OtherComponent
is lazily loaded and a fallback UI is displayed while it is being loaded.
Named Exports
You can use named exports when exporting multiple components.
export { ThingOne, ThingTwo };
In this example, ThingOne
and ThingTwo
can be imported and used in other parts of the app.
Optimizing Performance
Virtualize Long Lists
Use libraries like react-window
or react-virtualized
to virtualize long lists.
Avoid Inline Functions
Avoid using inline functions as they can prevent optimization in some circumstances.
Avoid Inline Object Literals
Avoid creating new objects or arrays inline, as this can negate some optimizations.
Accessible Forms
Labeling Controls
<label htmlFor="namedInput">Name:</label>
<input id="namedInput" type="text" name="name" />
In this example, the label
element is associated with the input
element using the for
attribute.
Managing Focus
Use the ref
attribute to manage focus.
class MyComponent extends React.Component {
constructor(props) {
super(props);
this.inputRef = React.createRef();
}
componentDidMount() {
this.inputRef.current.focus();
}
render() {
return <input ref={this.inputRef} />;
}
}
In this example, the input
is focused when the component is mounted.
Handling Key Events
Listen to keyboard events using event listeners.
class MyComponent extends React.Component {
handleKeyDown = (event) => {
if (event.key === 'Enter') {
console.log('Enter pressed');
}
}
render() {
return (
<input
type="text"
onKeyDown={this.handleKeyDown} />
);
}
}
In this example, the handleKeyDown
method handles the Enter
key event.
Accessibility in React
Naming Conventions
Follow naming conventions such as using aria-label
for screen readers.
DOM Representation
React generates a DOM where you can manage accessibility features.
Forms
Labels
Use labels for form controls to help screen readers map form controls to the form labels.
Dynamic Roles
You can use the role
attribute for dynamic roles.
ARIA Attributes
Use ARIA attributes to convey additional semantics to screen readers.
Debugging
Profiling the Performance of a Component
Use the Chrome React DevTools Profiler to profile the performance of a component.
Profiling Production Builds
You can profile the performance of a component in production builds using React Profiler
.
Identifying Resource Heavy Components
Identify the components that consume the most resources using profiling tools.
Identifying Concurrent Mode Issues
Use the React Profiler to identify issues in Concurrent Mode.
Security
JSX Injection Attacks
JSX code is safe from XSS attacks. React DOM escapes any values embedded in JSX before rendering them to the DOM, preventing code injection attacks.
Protecting Your Application from XSS Attacks
Always sanitize and validate any input data to protect your application from XSS attacks.
Avoiding Risks with Injection Attacks
Avoid using innerHTML or related properties that can lead to injection attacks.
Tools and Resources
Official Documentation
Refer to the official React documentation.
Community Resources
Join the React community to learn more and get help.
Courses and Tutorials
Take online courses and tutorials to deepen your understanding of React.
API Reference
React
ReactDOM
ReactDOM.render()
ReactDOM.hydrate()
ReactDOM.unmountComponentAtNode()
ReactDOM.createPortal()
ReactDOMServer
ReactDOMServer.renderToString()
ReactDOMServer.renderToStaticMarkup()
ReactDOMClient
ReactDOM.createRoot()
Concurrent Mode APIs
React.lazy()
Suspense
React.memo()
useDeferredValue()
useTransition()
Profiler
startTransition()
By understanding and effectively using the React Reference API, you can build robust and efficient web applications with better performance and maintainability. Each concept and component covered in this documentation serves a specific purpose, making React a powerful tool for building complex UIs efficiently.