There are two ways to write components in React. One is a function component and the other is a class component. Functional components have become more popular recently. Why?
This article will help you understand the difference between functional and class components and give you an insight into the modern React world by explaining each component with sample code!
Rendering JSX
First, the most obvious difference is grammar. The function component is just a normal JavaScript function that returns JSX. The class component is a JavaScript class that inherits react.component. it has a render function. Let’s look at a simple example.
import React from "react"; // Function component const FunctionalComponent = () => {return <h1>Hello, world</h1>; };Copy the code
When defining a class component, we must inherit from React.component. The JSX to render is returned in the Render method.
import React, { Component } from "react"; Class class Component extends Component {render() {return <h1>Hello, world</h1>; }}Copy the code
Component and the cords
Now let’s look at how the two components accept parameters. Suppose we want to pass in the string argument “MyName”.
<Component name="MyName" />
// Const FunctionalComponent = ({name}) => {return <h1>Hello, {name}</h1>; };Copy the code
In a function component, we pass component parameters as function parameters.
class ClassComponent extends React.Component { render() { const { name } = this.props; return <h1>Hello, { name }</h1>; }}Copy the code
For class components, we need this to refer to this parameter.
Dealing with the state
As we all know, in React projects, we can’t avoid dealing with the state variable. Previously, dealing with state could only be done in class components, but starting with React 16.8, React Hook useState was introduced to allow developers to write function components with state.
In the following example, we will make a simple counter that starts at 0 and increases the count by 1 with a click of the button.
const FunctionalComponent = () => {
const [count, setCount] = React.useState(0);
return (
<div>
<p>count: {count}</p>
<button onClick={() => setCount(count + 1)}>Click</button>
</div>
);
};
Copy the code
To use the state variable in a function component, we need to use the useState Hook, which requires an initial value. In this case, we start with a 0 click, so the initial value of count is 0.
Of course you can have many more types of initial values, including NULL, strings, and even objects — whatever JavaScript allows. On the left, since useState returns the current state and a function to update state, we structure the array this way. In this case, we’ll name them count and setCount to understand the connection between the two.
class ClassComponent extends React.Component { constructor(props) { super(props); this.state = { count: 0 }; } render() { return ( <div> <p>count: {this.state.count} times</p> <button onClick={() => this.setState({ count: this.state.count + 1 })}> Click </button> </div> ); }}Copy the code
In class components, state is handled a little differently. First, we need to know about the React.componentconstructor. Here are the definitions in the official documentation.
“The React component’s constructor is called before the component mounts. When using the constructor of the react.componentsubclass, you should first call super(props). Otherwise, this.props will not be defined in constructor, which may result in an error “.
Basically, if you don’t use constructor and call super(props), all the state variables you want to use will be undefined. So we define constructor first. Within constructor, we declare a state object with a key(count) and value(0). In JSX, we use this.state.count to access the value of the state key we defined in the constructor to display the count. Setters are similar, but the syntax is different.
Alternatively, you can write an onClick function. Remember that the argument to the setState function is state, and (optionally) props, if necessary.
onClick={() => this.setState((state) => { return { count: state.count + 1 }; })}Copy the code
The life cycle
Finally, let’s look at the life cycles of the two components.
On Mounting(componentDidMount)
The lifecycle function componentDidMount is called after the first rendering. There used to be a componentWillMount that occurred before the first render, but it will be removed in later releases, so it is not recommended for use in new projects.
const FunctionalComponent = () => { React.useEffect(() => { console.log("Hello"); } []); return <h1>Hello, World</h1>; };Copy the code
In function components, we use useEffect Hook instead of componentDidMount. The second argument to useState Hook is usually an array of changing states, and useEffect will only be called when these selected states change. But when it is an empty array, as in this example, it will be called once at mount time. This is the perfect replacement for componentDidMount.
class ClassComponent extends React.Component { componentDidMount() { console.log("Hello"); } render() { return <h1>Hello, World</h1>; }}Copy the code
Basically, class functions work the same way: componentDidMount is a lifecycle function that is called once after the first rendering.
On Unmounting(componentWillUnmount)
const FunctionalComponent = () => { React.useEffect(() => { return () => { console.log("Bye"); }; } []); return <h1>Bye, World</h1>; };Copy the code
We can also unmount using useState Hook. But be aware that the syntax is a little different. What we need to do is return a function in useEffect that runs at unmount. This is especially useful when you need to clean up functions such as clearInterval. One advantage of using useEffect is that we can write both mount and unload functions in the same place.
class ClassComponent extends React.Component { componentWillUnmount() { console.log("Bye"); } render() { return <h1>Bye, World</h1>; }}Copy the code
discuss
Both components have advantages and disadvantages, but functional components are increasingly replacing class components for the foreseeable future.
In our case, the functional component syntax is shorter and simpler, making it easier to develop, understand, and test. Class components can also be confusing with the heavy use of this. Using functional components can easily avoid this shortcoming and keep your code clean.
Also note that the React team is supporting more React Hooks for function components. In addition, the React team mentioned earlier that they would optimize the performance of function components by avoiding unnecessary checks and memory allocation. But it also promises not to make class components obsolete.
Also, in React, there are many different code styles. However, I prefer to use functional components rather than class components for the reasons listed above. I hope this article has helped you become more familiar with both components.
To read more articles, please follow my official account: Undefined Variables