For a while, the standard answer to this question was that class components provided access to more features (like state), but with Hooks now available, that is no longer the case.
You’ve probably heard the question of which of them performs better, and performance depends on what your code does rather than whether you choose to use a Function or a class component. In fact, the performance difference between the two is negligible, as can be seen from this comparison.
In this article, we look at the biggest differences between the two.
Rendered values (Captaure the Rendered values)
Remember: I’m not comparing Function to Classes. I’m just comparing react to Classes.
Compare these two pieces of code:
Function Component:
function ProfilePage(props) {
const showMessage = (a)= > {
alert("Followed " + props.user);
};
const handleClick = (a)= > {
setTimeout(showMessage, 3000);
};
return <button onClick={handleClick}>Follow</button>;
}Copy the code
Class Component:
class ProfilePage extends React.Component {
showMessage = (a)= > {
alert("Followed " + this.props.user);
};
handleClick = (a)= > {
setTimeout(this.showMessage, 3000);
};
render() {
return <button onClick={this.handleClick}>Follow</button>;
}Copy the code
Both component code describe the same logic: the user name passed in by the alert parent 3 seconds after the button is clicked. With this online Demo complete code, do the following to illustrate the difference between the two:
- Click the Follow button
- Before the 3 second popup, select Profile Select
- What value does watch Alert pop up
We can see:
The Class Component shows the modified values
Function Component displays the value before the modification:
In this example, the function component is displaying the desired result, because I clicked on follow and didn’t want to change the desired render result due to the parent props. Why is this the case with the class component?
class ProfilePage extends React.Component {
showMessage = (a)= > {
alert("Followed " + this.props.user);
};Copy the code
In the React class component, this is mutable, so a call to this. Props calls the latest props every time. The showMessage above is executed after 3 seconds, at which point the PROPS is up to date. Function Component has no syntax for this.props, so props is always immutable.
How to solve this problem?
One way is to read this props in the event-binding method and pass it to showMessage:
class ProfilePage extends React.Component {
showMessage = (user) = > {
alert('Followed ' + user);
};
handleClick = (a)= > {
const {user} = this.props;
setTimeout((a)= > this.showMessage(user), 3000);
};
render() {
return <button onClick={this.handleClick}>Follow</button>; }}Copy the code
But writing code like this is cumbersome, and if you want to call other methods in showMessage, This method also needs to read this.props. Somthing or this.state. Someting also needs to pass this.props or this.state, which is cumbersome.
Another way is to read props in the render function:
class ProfilePage extends React.Component {
render() {
// Capture the props!
const props = this.props;
// Note: we are *inside render*.
// These aren't class methods.
const showMessage = (a)= > {
alert('Followed ' + props.user);
};
const handleClick = (a)= > {
setTimeout(showMessage, 3000);
};
return <button onClick={handleClick}>Follow</button>; }}Copy the code
This may seem strange, but if simplified, it is the Function component.
Hooks also have the Capture Rendered Values feature
Look at the following code:
function MessageThread() {
const [message, setMessage] = useState(' ');
const showMessage = (a)= > {
alert('You said: ' + message);
};
const handleSendClick = (a)= > {
setTimeout(showMessage, 3000);
};
const handleMessageChange = (e) = > {
setMessage(e.target.value);
};
return (
<>
<input value={message} onChange={handleMessageChange} />
<button onClick={handleSendClick}>Send</button>
</>
);
}Copy the code
After clicking the Send button, change the value of the input field again. After 3 seconds, the output is the same as before clicking the input field. This means that Hooks also have capture Value features.
What if we want to avoid the capture Values feature and want to get the latest input field values? In the class component, we just need to access this.props, because this is mutable and can read the latest props.
Here we use useRef to circumvent capture Values:
function MessageThread() {
const [message, setMessage] = useState(' ');
// Keep track of the latest value.
const latestMessage = useRef(' ');
useEffect((a)= > {
latestMessage.current = message;
});
const showMessage = (a)= > {
alert('You said: ' + latestMessage.current);
};
const handleSendClick = (a)= > {
setTimeout(showMessage, 3000);
};
const handleMessageChange = (e) = > {
setMessage(e.target.value);
};
return (
<>
<input value={message} onChange={handleMessageChange} />
<button onClick={handleSendClick}>Send</button>
</>
);
}Copy the code
Conclusion:
The main difference between the function component and the class component is that the function component captures rendered values, whereas the class component always gets the latest props because this is mutable in React. As well as the function component, hooks have the Capture Values feature, which can be avoided with useRef.