As you might know, there are two ways to create a component in React, with functional component and class-based component.
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.
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.
Related Posts
- React Conditional Rendering (If Else) Best Practices with 7 Different Methods
- React Project Structure Best Practices for Scalable Application
What is Functional Component in React?
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.
Now, we can’t call it a stateless component anymore since it can also have states and lifecycles.
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.
How to Write React Functional Component?
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.
1. A Simple Stateless Component
A simple stateless component usually created when you need a reusable UI that don’t have any props/inputs or states.
This is a very basic component that you better write it as a functional component.
2. Handling Props
Suppose you want to add a stateless component with name
and role
prop. It will be called in the other components like this.
To handle inputs/props provided, you can access them as follows.
In a functional component, props passed through an argument (as object) that stores any input/prop as its property.
3. Props with PropTypes
To create a better component, you should define and validate the props. We can use PropTypes for that purpose.
With PropTypes, you can type-checking your props easily. If the props provided don’t match with defined type, it will trigger a warning.
For more details about PropTypes, you can go to this page.
4. A Stateful Component (with useState Hook)
Now, we can create a stateful functional component by using useState Hook.
Here is how you can use it.
useState hook used to declare a “state variable”. It returns a pair of values: the current state (helloMessage
), and a function that update it (setHelloMessage
).
They are equivalent to this.state.helloMessage
and this.setState
in the class-based component.
5. Handling Event
When users interact with components like form, button, link, etc, we want them to behave as we want.
Therefore, we need event handlers to handle events like onClick, onKeyup, onChange, and other supported react events here.
For instance, we want to change helloMessage
when users change the value of the input field. You can do that as follows.
Because we only need one line code to change the state, we can write the event handler inline as an arrow function.
If you want to add other codes when the input changes, you better write the event handler as a separate function as follows.
6. Handling Callback (Passing data from child to parent component)
In the real project, we often wrapping a component inside another component(parent component).
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 pass data from child to parent component.
We can do that with callback function.
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.
https://developer.mozilla.org/en-US/docs/Glossary/Callback\_function
Here is how you can listen or pass data from child to parent with callback function.
The callback function in the codes above is onChangeHelloMessage
that passed as a prop in ChildComponent
. The onChangeHelloMessage
value is invoked in the onInputChange
function.
Callback functions are also used frequently to create a reusable component that all of its states depend on the parent component who calls it.
For instance, we create a customized input component (eg. autocomplete, masked input) that shared across components.
As you can see, the ParentComponent
control the states that passed to ACustomizedInputComponent
and listen to the change made in ACustomizedInputComponent
.
7. Functional Component Lifecycle (useEffect Hook)
In a class-based component, there are lifecycle methods like componentDidMount
, componentDidUpdate
and componentWillUnmount
.
Thanks to useEffect
hook, we can now have the equivalent function to replace them.
By using useEffect
, 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.
In the real project, the useEffect
hook usually used to wrap an API calling function. You can see the usage in my tutorial about React Infinite scrolling.
For the simple example, you can look at the codes below.
This is equivalent to the codes below (in class-based component).
For further usage of useEffect, this post from Adrian Bece might help you to understand that.
Why should you use Functional Component instead of Class Component?
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.
1. Easier to Read, Shorter to Write
Compared to Class-based components, Functional components are easier to understand and shorter to write. Look at the codes below.
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.
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.
The shorter codes are easier to read.
2. Easier to Test
Since it is written as a plain javascript function, you can test a functional component like you test a function.
You don’t also have to worry about hidden state or side effects. For every input (props), functional components have exactly one output.
3. Potentially have Better Performance
In the release notes of function component, it said,
In the future, we’ll also be able to make performance optimizations specific to these components by avoiding unnecessary checks and memory allocations
This article also said that functional components are 45% faster than class-based component, even without optimization.
4. Enforced Best Practices
A functional component often used to create a presentational component that focuses on UI rather than behavior.
We should avoid using the state for this kind of component. States and lifecyles should be used in the higher level component
By using a functional component (as a stateless component), you keep your presentational component pure, without states and lifecycles.
5. The Future of React
Since Hooks introduced, many developers choose to use functional components because now it can do nearly everything that a class-based component can do.
So, why still use class-based components while functional components are better and many developers love it?