React hooks pros and cons

React hooks pros and cons

Preface

Hooks are a new feature in React 16.8. It is completely optional and 100% backwards compatible. It allows you to use functional components, class components and other features of react, such as state management, lifecycle hooks, etc. Conceptually, React components have always been more like functions. Hooks embrace functions without sacrificing the spirit of React.

advantage:

1. The code is more readable. The code logic of the same function was originally split into different lifecycle functions, which makes it difficult for developers to maintain and iterate. React Hooks can aggregate the functional codes for easy reading and maintenance. For example, each lifecycle often contains some unrelated logic. Generally we will get data in componentDidMount and componentDidUpdate. However, the same componentDidMount may also contain a lot of other logic, such as setting up event listeners, which then need to be cleared in componentWillUnmount. Code that is interrelated and needs to be modified in parallel is separated, while completely unrelated code is combined in the same method. This can easily lead to bugs and logical inconsistencies.
2. The component tree hierarchy becomes shallower. In the original code, we often use HOC/render props and other methods to reuse component states, enhance functions, etc., which undoubtedly increases the number of component tree layers and rendering. If you observe React applications in React DevTools, you will find that components composed of providers, consumers, higher-order components, render props and other abstract layers will form a "nested hell". In React Hooks, these functions can be implemented through powerful custom Hooks.
3. No need to consider where this points to. In class components, you have to understand how this works in JavaScript.

shortcoming:

1. Responsive useEffect

When writing function components, you have to change some writing habits. You must be aware of when the "dependency array" of useEffect and useCallback changes in your code. Sometimes, your useEffect depends on the immutability of a function, and the immutability of this function depends on the immutability of another function, thus forming a dependency chain. Once a node in this dependency chain is accidentally changed, your useEffect will be accidentally triggered. If your useEffect is an idempotent operation, it may cause performance problems. If it is non-idempotent, it will be terrible.

Therefore, compared with componentDidmount and componentDidUpdate, useEffect brings a greater mental burden.

2. Status is not synchronized

Functions run independently, and each function has an independent scope. The variables of the function are stored in the runtime scope. When we have asynchronous operations, we often encounter the variable reference of the asynchronous callback is the previous one, that is, the old one (which can also be understood as a closure here). For example, the following example:

import React, { useState } from "react";
​
const Counter = () => {
  const [counter, setCounter] = useState(0);
​
  const onAlertButtonClick = () => {
    setTimeout(() => {
      alert("Value: " + counter);
    }, 3000);
  };
​
  return (
    <div>
      <p>You clicked {counter} times.</p>
      <button onClick={() => setCounter(counter + 1)}>Click me</button>
      <button onClick={onAlertButtonClick}>
        Show me the value in 3 seconds
      </button>
    </div>
  );
};
​
export default Counter;

When you click Show me the value in 3 seconds, and then click Click me, the value of the counter changes from 0 to 1. Three seconds later, the timer is triggered, but the alert shows 0 (old value), but we want the current state to be 1.

This problem does not occur in class components, because the properties and methods of class components are stored in an instance, and the calling methods are: this.state.xxx and this.method(). Because each time the value is taken from an unchanged instance, there is no problem of old references.

In fact, to solve this hooks problem, you can also refer to the instance of the class. The immutable RefObject (the current property is mutable) returned by useRef is used to save the state, and the value access method is changed from counter to: counterRef.current. as follows:

import React, { useState, useRef, useEffect } from "react";
​
const Counter = () => {
  const [counter, setCounter] = useState(0);
  const counterRef = useRef(counter);
​
  const onAlertButtonClick = () => {
    setTimeout(() => {
      alert("Value: " + counterRef.current);
    }, 3000);
  };
​
  useEffect(() => {
    counterRef.current = counter;
  });
​
  return (
    <div>
      <p>You clicked {counter} times.</p>
      <button onClick={() => setCounter(counter + 1)}>Click me</button>
      <button onClick={onAlertButtonClick}>
        Show me the value in 3 seconds
      </button>
    </div>
  );
};
​
export default Counter;

The result is what we expected, the alert is the current value 1.

How to avoid common problems with react hooks

  • Don't write too many dependencies in useEffect, divide these dependencies into multiple single-function useEffect. In fact, this follows the "single responsibility model" of software design.
  • If you run into issues with out-of-sync states, consider passing parameters to the function manually. like:
   // showCount's count comes from the parent scope const [count,setCount] = useState(xxx); 
   function showCount(){ console.log(count) } 

   // showCount's count comes from parameter const [count, setCount] = useState(xxx); 
   function showCount(c){ console.log(c) }

But this only solves part of the problem, and many times you have to use the useRef solution mentioned above.

3. Pay attention to the warnings of the eslint-plugin-react-hooks plugin.

4. For complex business, use Component instead of hooks.

The above is the detailed content of the advantages and disadvantages of React hooks. For more information about the advantages and disadvantages of React hooks, please pay attention to other related articles on 123WORDPRESS.COM!

You may also be interested in:
  • React Hooks Detailed Explanation
  • Common pitfalls of using React Hooks
  • React tips teach you how to get rid of hooks dependency troubles
  • 30 minutes to give you a comprehensive understanding of React Hooks
  • How React Hooks Work
  • React's transition from Class to Hooks

<<:  Detailed explanation of the EXPLAIN command and its usage in MySQL

>>:  Detailed explanation of the usage of common Linux commands (Part 2) ———— Text editor commands vi/vim

Recommend

Solve the error of installing VMware Tools on Ubuntu 18.04

1. According to the online tutorial, the installa...

vue $set implements assignment of values ​​to array collection objects

Vue $set array collection object assignment In th...

Mysql join table and id auto-increment example analysis

How to write join If you use left join, is the ta...

Vue implements horizontal scrolling of marquee style text

This article shares the specific code for Vue to ...

Several ways to update batches in MySQL

Typically, we use the following SQL statement to ...

Linux CentOS MySQL database installation and configuration tutorial

Notes on installing MySQL database, share with ev...

Several implementation methods of the tab bar (recommended)

Tabs: Category + Description Tag bar: Category =&...

Detailed explanation of WeChat Mini Program official face verification

The mini program collected user personal informat...

Guide to Efficient Use of MySQL Indexes

Preface I believe most people have used MySQL and...

Vue.js manages the encapsulation of background table components

Table of contents Problem Analysis Why encapsulat...

MySQL 8.0.14 installation and configuration method graphic tutorial (general)

MySQL service 8.0.14 installation (general), for ...

How to publish a locally built docker image to dockerhub

Today we will introduce how to publish the local ...