Types of Components in React
Tags: react, javascript
Published: 2020-05-21 02:55:10

There are two types of components in React: function and class.

## Function Component
Function components are the simplest way to write a component. To write a function component, just declare a function.

``` javascript
import React from "react";

function Book(props) {
  return <h1>{props.book.title}</h1>
}

export default Book
```
Remember to import React in order to return a JSX element.

With ES6, you can now use arrow functions to define a function component. If you have a simple component, you can even take advantage of the implicit return that comes with arrow functions. If you are only passing one argument, you can drop the parentheses.

``` javascript
// should also have imports and exports here

const Book = (props) => {
  return <h1>{props.book.title}</h1>
}

const Book = props => <h1>{props.book.title}</h1>
```


## Class Component
Class components are defined using the ES6 `class`.

Unlike function components, class components use a `render` method to return JSX. A class component must have the `render` method.


``` javascript
import React from "react";

class Book extends React.Component {
  render() {
    return <h1>{this.props.book.title}</h1>
  }
}

export default Book
```


### Differences when using props
In function components, props must be explicitly passed as an argument in order to use the props.


In class components, access props by writing `this.props.book`. We do not need to explicitly pass in props to use it, unless we are trying to access props in the `constructor` method.

If for some reason you want to save the author from props to the state of the component, you can do so like this (however, usually you don't want to initialize state from props because it creates a second source of truth):

``` javascript
// function
const Book = props => <h1>{props.book.title}</h1>

// class
class Book extends React.Component {
  constructor(props) {
    super();
    this.state = {
      author: props.book.author
    };
  }

  render() {
    return <h1>{this.props.book.title}</h1>
  }
}
```

### State
Function components do not have state. However, React Hooks now make it possible to use state in function components. I do not talk about hooks in this article, but you can read more about it in the [React Docs](https://reactjs.org/docs/hooks-intro.html). If you are going to need state to store data that you know is going to change, then use a class component. Class components extend React's Component class, which gives the component the ability to have state. You can set initial state like in the example above, or now with ES7, we can use the `state` property to set initial state:

```javascript
class Book extends React.Component {
  state = {
    author: this.props.book.author
  }

  render() {
    return <h1>{this.props.book.title}</h1>
  }
}
```

### Which one should I use?
Use function components when you simply want the component to display content. In this example, we just want to display a book's information.

```javascript
const Book = (props) => {
  return <div>
    <h1>{props.book.title}</h1>
    <h3>{props.book.author}</h3>
    <p>{props.book.summary}</p>
  </div>
}
```

If you know that you are going to be writing more business logic, need state, or making fetch request to an API, then use a class component. Also, if you need to use any lifecycle methods, such as `componentDidMount`, use a class component. Function components do not have lifecycle methods. 

I like to start with a class component if I'm not sure which one to use. Later on, when I know the component will only be rendering content, I'll change it into a function component. 

It is a good idea to change class components to function components. Function components are more stable and predictable because it returns the same thing every time, as long as the props are the same. Functional components update based on prop changes or if their parent component re-renders. When other developers see that you are using a function component, they can easily understand your intentions.

Thanks for reading!