React Components
Components are the core of React. They are independent, reusable pieces of code that manage their own state and view. Conceptually, components are like JavaScript functions. They accept arbitrary inputs (called "props") and return React elements that describe what should appear on the screen.
Function Components and Class Components
The simplest way to define a component is by writing a JavaScript function:
// This is a function component
function Welcome(props) {
return <h1>Hello, {props.name}</h1>;
}This function is a valid React component because it accepts a single props object parameter and returns a React element.
You can also define a component using ES6 class:
// This is a Class component
class Welcome extends React.Component {
render() {
return <h1>Hello, {this.props.name}</h1>;
}
}In modern React, function components with Hooks are the most commonly used and recommended approach. They are more concise and easier to understand. We will primarily use function components throughout this tutorial.
Rendering Components
Previously, we only encountered React elements that represent DOM tags:
const element = <div />;However, elements can also represent custom components:
const element = <Welcome name="Sara" />;When React sees an element representing a custom component, it passes the JSX attributes as a single object to that component. This object is called props.
For example, this code will render "Hello, Sara" on the page:
import React from 'react';
import ReactDOM from 'react-dom/client';
function Welcome(props) {
return <h1>Hello, {props.name}</h1>;
}
const root = ReactDOM.createRoot(document.getElementById('root'));
const element = <Welcome name="Sara" />;
root.render(element);Let's review what happened here:
- We call
root.render()and pass in the<Welcome name="Sara" />element. - React calls the
Welcomecomponent, passing{name: 'Sara'}as thepropsobject. - The
Welcomecomponent returns a<h1>Hello, Sara</h1>element as the result. - React DOM efficiently updates the DOM to match
<h1>Hello, Sara</h1>.
Important Note: Component names must start with an uppercase letter. React treats components starting with a lowercase letter as native DOM tags. For example,
<div />represents an HTML div tag, while<Welcome />represents a component.
Composing Components
Components can reference other components in their output. This allows us to use the same component abstraction to handle arbitrary levels of detail. A button, a form, a dialog, a screen: in React applications, these are typically all represented as components.
For example, we can create an App component that renders multiple Welcome components:
function Welcome(props) {
return <h1>Hello, {props.name}</h1>;
}
function App() {
return (
<div>
<Welcome name="Sara" />
<Welcome name="Cahal" />
<Welcome name="Edite" />
</div>
);
}Typically, new React applications will have a top-level App component that contains the entire application.
Extracting Components
Don't be afraid to split components into smaller pieces.
Consider this Comment component:
function Comment(props) {
return (
<div className="Comment">
<div className="UserInfo">
<img className="Avatar" src={props.author.avatarUrl} alt={props.author.name} />
<div className="UserInfo-name">{props.author.name}</div>
</div>
<div className="Comment-text">{props.text}</div>
<div className="Comment-date">{formatDate(props.date)}</div>
</div>
);
}This component is difficult to modify because it contains too many nested structures. We can extract some smaller components from it.
First, we extract Avatar:
function Avatar(props) {
return (
<img className="Avatar" src={props.user.avatarUrl} alt={props.user.name} />
);
}Then, we extract UserInfo, which renders Avatar internally:
function UserInfo(props) {
return (
<div className="UserInfo">
<Avatar user={props.user} />
<div className="UserInfo-name">{props.user.name}</div>
</div>
);
}Now we can simplify the Comment component:
function Comment(props) {
return (
<div className="Comment">
<UserInfo user={props.author} />
<div className="Comment-text">{props.text}</div>
<div className="Comment-date">{formatDate(props.date)}</div>
</div>
);
}Component extraction may seem like heavy work at first, but it pays huge dividends in large applications. A good rule of thumb is that if a part of your UI is used multiple times (like Button, Panel), or if it's complex enough on its own (like App, FeedStory, Comment), then it's a good candidate to be extracted into an independent component.
Next, we will learn about a key feature of components: State.
Continue Learning: Next Chapter - React State