Course: Section

Get Started with Modern React: Step by Step

Episode: Title

S02・V22: Composition vs. Inheritance (Part 2)

Date Created: July 17th, 2019
Last Updated: 27 days ago

Objectives
  1. We will show that composition also works well for stateful components.
  2. We will discuss inheritance with respect to React.
Watch Video
Duration: 4m 14s

Composition for Stateful Components

Composition works equally well for stateful components. We will continue with the example from the previous video.

src/index.js
import React from "react";
import ReactDOM from "react-dom";

import "./index.css";

const FancyBorder = props => {
  return (
    <div className={`FancyBorder FancyBorder-${props.color}`}>
      {props.children}
    </div>
  );
};

const Dialog = props => {
  return (
    <FancyBorder color="blue">
      <h1 className="Dialog-title">{props.title}</h1>
      <p className="Dialog-message">{props.message}</p>
    </FancyBorder>
  );
};

const WelcomeDialog = props => {
  return (
    <Dialog
      title="Welcome"
      message="Thank you for visiting our spacecraft!"
    />
  );
};

ReactDOM.render(
  <WelcomeDialog />,
  document.getElementById("root")
);

First, we will import the useState hook.

import React, { useState } from "react";

Instead of the WelcomeDialog, we will have a stateful SignUpDialog. We will have the component remember the login of the user in local state. The initial login state will be the empty string.

const SignUpDialog = () => {
  const [login, setLogin] = useState("");

  return (
    <Dialog
      title="Welcome"
      message="Thank you for visiting our spacecraft!"
    />
  );
};

Next, we will add some children elements to the returned Dialog element. The first child will be an input for the login. When the input changes, we will fire a change handler, which we will define shortly. The second child will be a button for the user to sign up. We will add a click handler to the button, which we will also define shortly.

const SignUpDialog = () => {
  const [login, setLogin] = useState("");

  return (
    <Dialog
      title="Welcome"
      message="Thank you for visiting our spacecraft!"
    >      <input value={login} onChange={handleChange} />      <button onClick={handleSignUp}>Sign Me Up!</button>    </Dialog>  );
};

Now, we will define the handlers. The input change handler called handleChange will set the login to be the event target’s current value. The button click handler called handleSignUp will show an alert welcoming the user.

Finally, the added input and button children will need to be added to the Dialog component via props.

import React, { useState } from "react";
import ReactDOM from "react-dom";

import "./index.css";

const FancyBorder = props => {
  return (
    <div className={`FancyBorder FancyBorder-${props.color}`}>
      {props.children}
    </div>
  );
};

const Dialog = props => {
  return (
    <FancyBorder color="blue">
      <h1 className="Dialog-title">{props.title}</h1>
      <p className="Dialog-message">{props.message}</p>
      {props.children}    </FancyBorder>
  );
};

const SignUpDialog = () => {
  const [login, setLogin] = useState("");

  const handleChange = event => setLogin(event.target.value);  const handleSignUp = () => alert(`Welcome aboard, ${login}`);
  return (
    <Dialog
      title="Mars Exploration Program"
      message="How should we refer to you?"
    >
      <input value={login} onChange={handleChange} />
      <button onClick={handleSignUp}>Sign Me Up!</button>
    </Dialog>
  );
};

ReactDOM.render(
  <SignUpDialog />,
  document.getElementById("root")
);

Save the file and test the SignUpDialog in the browser.

Inheritance

We will now turn to the topic of “inheritance”. Facebook reports that it uses React in thousands of components, and they haven’t found any use cases where they would recommend creating component inheritance hierarchies.

Props and composition give you all the flexibility you need to customize a component’s look and behavior in an explicit and safe way. Remember that components may accept arbitrary props, including primitive values, React elements, or functions.

If you want to reuse non-UI functionality between components, we suggest extracting it into a separate JavaScript module. The components may import it and use that function, object, or a class, without extending it.

Summary

We showed that composition also works well for stateful components, and we discussed inheritance with respect to React.

Next Up…

In the next video, we will start a six-part series called “Thinking in React”.