Skip to content

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:

javascript
// 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:

javascript
// 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:

javascript
const element = <div />;

However, elements can also represent custom components:

javascript
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:

javascript
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:

  1. We call root.render() and pass in the <Welcome name="Sara" /> element.
  2. React calls the Welcome component, passing {name: 'Sara'} as the props object.
  3. The Welcome component returns a <h1>Hello, Sara</h1> element as the result.
  4. 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:

javascript
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:

javascript
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:

javascript
function Avatar(props) {
  return (
    <img className="Avatar" src={props.user.avatarUrl} alt={props.user.name} />
  );
}

Then, we extract UserInfo, which renders Avatar internally:

javascript
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:

javascript
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

Content is for learning and research only.