React Functional Component with Hooks: Everything You Need To Know
Tags: javascript, react, webdev, tutorial
Published: 2020-09-11 14:37:01

This post was originally published at <a href="https://www.devaradise.com/react-functional-component-with-hooks">https://www.devaradise.com/react-functional-component-with-hooks</a>

<!-- wp:paragraph -->
<p>As you might know, there are two ways to create a component in React, with functional component and class-based component.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Before React 16.8 released on February 16, 2019, we always use a class-based component to create a stateful component (a React component with states). Back then, a functional component only used when we create a stateless component.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Now, since React Hooks introduced in version 16.8, we can create a stateful component without declaring a class. We can "hook into" React state and lifecycle features from a function component with Hooks.</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":4} -->
<h4>Related Posts</h4>
<!-- /wp:heading -->

<!-- wp:list -->
<ul><li><a href="https://www.devaradise.com/react-conditional-rendering-if-else" target="_blank" rel="noreferrer noopener">React Conditional Rendering (If Else) Best Practices with 7 Different Methods</a></li><li><a href="https://www.devaradise.com/react-project-folder-structure" target="_blank" rel="noreferrer noopener">React Project Structure Best Practices for Scalable Application</a></li></ul>
<!-- /wp:list -->

<!-- wp:heading -->
<h2>What is Functional Component in React?</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>A Functional Component is a React Component declared with a plain javascript function that takes props and returns JSX. Before Hooks introduced, it's also known as a Stateless Component. </p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Now, we can't call it a stateless component anymore since it can also have states and lifecycles.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>With the existence of Hooks, React functional component can replace the class-based component as it's easier and shorter to write, easy to test, and has better performance. </p>
<!-- /wp:paragraph -->

<!-- wp:heading -->
<h2>How to Write React Functional Component?</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>We can create any type of react component with a functional component, from a stateless component to a complex component that has states and lifecycles.</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":3} -->
<h3>1. A Simple Stateless Component</h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>A simple stateless component usually created when you need a reusable UI that don't have any props/inputs or states.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>This is a very basic component that you better write it as a functional component.</p>
<!-- /wp:paragraph -->

```javascript
import React from 'react'

export default function StatelessComponent() {
  return (
    <div>
      I am a stateless component
    </div>
  )
}
```

<!-- wp:heading {"level":3} -->
<h3>2. Handling Props</h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>Suppose you want to add a stateless component with <code>name</code> and <code>role</code> prop. It will be called in the other components like this.</p>
<!-- /wp:paragraph -->

<!-- wp:code {"lineNumbers":false} -->
```javascript
<StatelessComponent name="Syakir" role="Front-end Developer"/>
```

<!-- wp:paragraph -->
<p>To handle inputs/props provided, you can access them as follows.</p>
<!-- /wp:paragraph -->

```javascript
import React from 'react'

export default function StatelessComponent(props) {
  return (
    <div>
      Hi, I am {props.name}<br/>
      I am a {props.role}
    </div>
  )
}
```

<!-- wp:paragraph -->
<p>In a functional component, props passed through an argument (as object) that stores any input/prop as its property. </p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":3} -->
<h3>3. Props with PropTypes</h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>To create a better component, you should define and validate the props. We can use PropTypes for that purpose.</p>
<!-- /wp:paragraph -->

```javascript
import React from 'react';
import PropTypes from 'prop-types';

export default function StatelessComponent(props) {
  return (
    <div>
      Hi, I am {props.name}<br/>
      I am a {props.age} years old {props.role}
    </div>
  )
}

StatelessComponent.propTypes = {
  name: PropTypes.string.isRequired,
  role: PropTypes.string.isRequired,
  age: PropTypes.number.isRequired
};
```

<!-- wp:paragraph -->
<p>With PropTypes, you can type-checking your props easily. If the props provided don't match with defined type, it will trigger a warning.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>For more details about PropTypes, you can go to <a href="https://reactjs.org/docs/typechecking-with-proptypes.html" target="_blank" rel="noreferrer noopener nofollow">this page</a>.</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":3} -->
<h3>4. A Stateful Component (with useState Hook)</h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>Now, we can create a stateful functional component by using useState Hook.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Here is how you can use it. </p>
<!-- /wp:paragraph -->

```javascript
import React, { useState } from 'react'

export default function StatefulComponent() {
  const [helloMessage, setHelloMessage] = useState('Hello world!');

  return (
    <div>
      <input type="text" value={helloMessage}/>
    </div>
  )
}

```

<!-- wp:paragraph -->
<p>useState hook used to declare a "state variable". It returns a pair of values: the current state (<code>helloMessage</code>), and a function that update it (<code>setHelloMessage</code>).</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>They are equivalent to <code>this.state.helloMessage</code> and <code>this.setState</code> in the class-based component.</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":3} -->
<h3>5. Handling Event</h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>When users interact with components like form, button, link, etc, we want them to behave as we want. </p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Therefore, we need event handlers to handle events like onClick, onKeyup, onChange, and <a href="https://reactjs.org/docs/events.html" target="_blank" rel="noreferrer noopener nofollow">other supported react events here</a>.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>For instance, we want to change <code>helloMessage</code> when users change the value of the input field. You can do that as follows.</p>
<!-- /wp:paragraph -->

```javascript
import React, { useState } from 'react'

export default function StatefulComponent() {
  const [helloMessage, setHelloMessage] = useState('Hello world!');

  return (
    <div>
      <input type="text" value={helloMessage} onChange={(e) => setHelloMessage(e.target.value)}/>
      {helloMessage}
    </div>
  )
}
```

<!-- wp:paragraph -->
<p>Because we only need one line code to change the state, we can write the event handler inline as an arrow function. </p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>If you want to add other codes when the input changes, you better write the event handler as a separate function as follows.</p>
<!-- /wp:paragraph -->

```javascript
import React, { useState } from 'react'

export default function StatefulComponent() {
  const [helloMessage, setHelloMessage] = useState('Hello world!');

  const onInputChange = (e) => {
    setHelloMessage(e.target.value);
    // other codes
  }

  return (
    <div>
      <input type="text" value={helloMessage} onChange={onInputChange}/>
      {helloMessage}
    </div>
  )
}

```

<!-- wp:heading {"level":3} -->
<h3>6. Handling Callback (Passing data from child to parent component)</h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>In the real project, we often wrapping a component inside another component(parent component). </p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>In many cases, we need to listen to what happened in child component, and create a handler in the parent component. Simply, we need to <strong>pass data from child to parent component</strong>.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>We can do that with callback function.</p>
<!-- /wp:paragraph -->

<!-- wp:quote -->
<blockquote class="wp-block-quote"><p>A callback function is a function passed into another function as an argument, which is then invoked inside the outer function to complete some kind of routine or action.</p><cite>https://developer.mozilla.org/en-US/docs/Glossary/Callback_function</cite></blockquote>
<!-- /wp:quote -->

<!-- wp:paragraph -->
<p>Here is how you can listen or pass data from child to parent with callback function. </p>
<!-- /wp:paragraph -->

```javascript
import React, {useState} from 'react';

export default function ParentComponent() {
  const [messageFromChild, setMessageFromChild] = useState('');

  return (
    <div>
      parent should listen 'messageFromChild' when it changed: {messageFromChild}
      <br/><br/>
      <ChildComponent onChangeHelloMessage={(e) => setMessageFromChild(e)}/>
    </div>
  )
}

function ChildComponent({onChangeHelloMessage}) {
  const [helloMessage, setHelloMessage] = useState('Hello world!');

  const onInputChange = (e) => {
    setHelloMessage(e.target.value);
    onChangeHelloMessage(e.target.value);
  }
 
  return (
    <div>
      <input type="text" value={helloMessage} onChange={onInputChange}/>
      {helloMessage}
    </div>
  )
}

```

<!-- wp:paragraph -->
<p>The callback function in the codes above is <code>onChangeHelloMessage</code> that passed as a prop in <code>ChildComponent</code>. The <code>onChangeHelloMessage</code> value is invoked in the <code>onInputChange</code> function.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Callback functions are also used frequently to create a reusable component that all of its states depend on the parent component who calls it.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>For instance, we create a customized input component (eg. autocomplete, masked input) that shared across components.</p>
<!-- /wp:paragraph -->

```javascript
import React, {useState} from 'react';

export default function ParentComponent() {
  const [customizedInputValue, setCustomizedInputValue] = useState('');

  return (
    <div>
      <ACustomizedInputComponent value={customizedInputValue} onChangeValue={(e) => setCustomizedInputValue(e.target.value)}/>
      <br/>    
      {customizedInputValue}
    </div>
  )
}

function ACustomizedInputComponent({value, onChangeValue}) {
  // Write some functions here that make this as a customized component.
  return (
    <div>
      {/* Just pretend this is a customized input that can't handled with the common input field */}
      <input type="text" value={value} onChange={onChangeValue}/>
    </div>
  )
}

```

<!-- wp:paragraph -->
<p>As you can see, the <code>ParentComponent</code> control the states that passed to <code>ACustomizedInputComponent</code> and listen to the change made in <code>ACustomizedInputComponent</code>. </p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":3} -->
<h3>7. Functional Component Lifecycle (useEffect Hook)</h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>In a class-based component, there are lifecycle methods like <code>componentDidMount</code>, <code>componentDidUpdate</code>&nbsp;and&nbsp;<code>componentWillUnmount</code>.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Thanks to <code>useEffect</code> hook, we can now have the equivalent function to replace them.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>By using <code>useEffect</code>, you tell React that your component needs to do something after render. React will remember the function you passed, and call it later after performing the DOM updates. </p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>In the real project, the <code>useEffect</code> hook usually used to wrap an API calling function. You can see the usage in my tutorial about <a href="https://www.devaradise.com/react-infinite-scroll-tutorial">React Infinite scrolling</a>.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>For the simple example, you can look at the codes below.</p>
<!-- /wp:paragraph -->

```javascript
import React, { useState, useEffect } from 'react';

function Example() {
  const [count, setCount] = useState(0);

  useEffect(() => {
    document.title = `You clicked ${count} times`;
  });

  return (
    <div>
      <p>You clicked {count} times</p>
      <button onClick={() => setCount(count + 1)}>
        Click me
      </button>
    </div>
  );
}
```

<!-- wp:paragraph -->
<p>This is equivalent to the codes below (in class-based component).</p>
<!-- /wp:paragraph -->

```javascript
class Example extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      count: 0
    };
  }

  componentDidMount() {
    document.title = `You clicked ${this.state.count} times`;
  }
  componentDidUpdate() {
    document.title = `You clicked ${this.state.count} times`;
  }

  render() {
    return (
      <div>
        <p>You clicked {this.state.count} times</p>
        <button onClick={() => this.setState({ count: this.state.count + 1 })}>
          Click me
        </button>
      </div>
    );
  }
}
```

<!-- wp:paragraph -->
<p>For further usage of useEffect, <a href="https://dev.to/prototyp/react-useeffect-explained-with-lifecycle-methods-296n" target="_blank" rel="noreferrer noopener">this post from Adrian Bece</a> might help you to understand that.</p>
<!-- /wp:paragraph -->

<!-- wp:heading -->
<h2>Why should you use Functional Component instead of Class Component?</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>If you are still have a doubt to adopt functional components as a whole in your React App, here are the complete reasons why you should use Functional Components instead of Class Components.</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":3} -->
<h3>1. Easier to Read, Shorter to Write</h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>Compared to Class-based components, Functional components are easier to understand and shorter to write. Look at the codes below.</p>
<!-- /wp:paragraph -->

<!-- wp:code {"lineNumbers":true} -->
```javascript
import React from 'react';

class Example extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      count: 0
    };
  }

  render() {
    return (
      <div>
        <p>You clicked {this.state.count} times</p>
        <button onClick={() => this.setState({ count: this.state.count + 1 })}>
          Click me
        </button>
      </div>
    );
  }
}
```

```javascript
import React, { useState } from 'react';

function Example() {
  const [count, setCount] = useState(0);

  return (
    <div>
      <p>You clicked {count} times</p>
      <button onClick={() => setCount(count + 1)}>
        Click me
      </button>
    </div>
  );
}
```

<!-- wp:paragraph -->
<p>Both code blocks are the same components but declared different ways. The first code block declared with a class-based component, while the second code block declared with a functional component.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>With the functional component, you only need 14 lines of code for the Example component. On the other hand, you will have to write 24 lines of code if you declare it with a class-based component.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>The shorter codes are easier to read.</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":3} -->
<h3>2. Easier to Test</h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>Since it is written as a plain javascript function, you can test a functional component like you test a function. </p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>You don't also have to worry about hidden state or&nbsp;side effects. For every input (props), functional components have exactly one output. </p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":3} -->
<h3>3. Potentially have Better Performance</h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>In the release notes of function component, it said,</p>
<!-- /wp:paragraph -->

<!-- wp:quote -->
<blockquote class="wp-block-quote"><p>In the future, we’ll also be able to make performance optimizations specific to these components by avoiding unnecessary checks and memory allocations</p></blockquote>
<!-- /wp:quote -->

<!-- wp:paragraph -->
<p><a href="https://medium.com/missive-app/45-faster-react-functional-components-now-3509a668e69f" target="_blank" rel="noreferrer noopener">This article</a> also said that functional components are 45% faster than class-based component, even without optimization.</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":3} -->
<h3>4. Enforced Best Practices</h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>A functional component often used to create a presentational component that focuses on UI rather than behavior. </p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>We should avoid using the state for this kind of component. States and lifecyles should be used in the higher level component</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>By using a functional component (as a stateless component), you keep your presentational component pure, without states and lifecycles.</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":3} -->
<h3>5. The Future of React</h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>Since Hooks introduced, many developers choose to use functional components because now it can do nearly everything that a class-based component can do.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>So, why still use class-based components while functional components are better and many developers love it? </p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p></p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p> </p>
<!-- /wp:paragraph -->