Two Types of Component

Two Types of Component
WIP

One of React’s defining features is that it allows you to create custom element types, called components. And while so far this guide has focused on defining components with functions, React also lets you define components with classes.

But why have two types of components? Well, as you know, function components are a little limited. All they know about is their current props. They can’t access previous props or external state. And they’re only re-rendered when their parent is; they can’t be re-rendered individually.

In contrast, class components can communicate with the outside world, can re-render their children without re-rendering the whole app, and can store state between renders. Which leads to the major difference between the two types of component:

  1. Function components always output the same element for the same value of props.
  2. Class components can output different elements for the same value of props.

We’ll get to how this works in a moment. But first…

#How do I define class components?

You just wrap a function component in a class! There are just three rules:

  1. The class must extend from React.Component
  2. You must define a render() method that returns a React element
  3. Props are accessed through this.props instead of through function arguments

Other than that, class components are the same as function components. They both support the special propTypes and defaultProps properties. They both can be passed to createElement as the type argument. And they both use the CamelCase naming convention.

In fact, any function component can be rewritten as a class component. For example, here’s how you’d rewrite the Contact component from earlier as a class component:

index.js
styles.css
import PropTypes from 'prop-types'
import React from 'react'
import ReactDOM from 'react-dom'
import './styles.css'

class Contact extends React.Component {
  render() {
    return (
      <div className='Contact'>
        <span className='Contact-name'>
          {this.props.name}
        </span>
        <a href={"mailto:"+this.props.email}>
          {this.props.email}
        </a>
      </div>
    )
  }
}

Contact.propTypes = {
  name: PropTypes.string.isRequired,
  email: PropTypes.string.isRequired,
}

ReactDOM.render(
  React.createElement(
    Contact,
    {
      name: 'James K Nelson',
      email: 'james@frontarm.com',
    }
  ),
  document.getElementById('root')
)
Build In Progress

#Let’s make a contact form!

To get familiar with class components, I have an exercise for you.

Your task is to create a class component that renders a read-only form like this one:

I’ve started you off with the skeleton of a class component. I’ve also set its propTypes property, which you can use to find which props the component expects.

A ContactForm CSS class is available in styles.css. Make sure to apply it to the form using the className prop.

Once you’re done, we’ll learn how to hook those inputs up!

index.js
styles.css
import PropTypes from 'prop-types'
import React from 'react'
import ReactDOM from 'react-dom'
import './styles.css'

class ContactForm extends React.Component {
  // Your task is to implement this class
}

ContactForm.propTypes = {
  name: PropTypes.string.isRequired,
  email: PropTypes.string.isRequired,
}

ReactDOM.render(
  <ContactForm
    name='James K Nelson'
    email='james@frontarm.com'
  />,
  document.getElementById('root')
)
Build In Progress
Progress to next section.