React tips teach you how to get rid of hooks dependency troubles

React tips teach you how to get rid of hooks dependency troubles

A very common scenario in react projects:

const [watchValue, setWatchValue] = useState('');
const [otherValue1, setOtherValue1] = useState('');
const [otherValue2, setOtherValue2] = useState('');

useEffect(() => {
    doSomething(otherValue1, otherValue2);
}, [watchValue, otherValue1, otherValue2]);

We want to execute doSomething when watchValue changes, which will reference other values otherValue1 and otherValue2 .

Here comes a troubling question:

  • If otherValue1 and otherValue2 are not added to the dependency array, doSomething is likely to access the old variable references of otherValue1 and otherValue2 , resulting in unexpected errors (if hooks -related eslint is installed, a warning will be prompted).
  • On the contrary, if otherValue1 and otherValue2 are added to the dependency array, doSomething will also be executed when these two values ​​change, which is not what we want (we only want to reference their values, but do not want them to trigger doSomething ).

This problem can be solved by changing otherValue1 and otherValue2 into ref :

const [watchValue, setWatchValue] = useState('');
const other1 = useRef('');
const other2 = useRef('');

// ref does not need to be added to the dependency array because the reference remains unchanged useEffect(() => {
    doSomething(other1.current, other2.current);
}, [watchValue]);

In this way, the variable references of other1 and other2 will not change, which solves the previous problem, but introduces a new problem: when the current value of other1 and other2 changes, it will not trigger component re-rendering (changes useRef的current will not trigger component rendering), so the interface will not be updated when the value changes!

This is a headache in hooks . The useState variable will trigger re-rendering and keep the interface updated, but when it is used as a dependency of useEffect , it will always trigger unwanted function execution. The useRef variable can be safely used as a useEffect dependency, but it will not trigger component rendering and the interface will not be updated.
How to solve it?

You can combine the features of useRef and useState to construct a new hooks function: useStateRef .

import { useState, useRef } from "react";

// Use the reference trait of useRef while maintaining the responsiveness of useState type StateRefObj<T> = {
  _state: T;
  value: T;
};
export default function useStateRef<T>(
  initialState: T | (() => T)
): StateRefObj<T> {
  // Initialization value const [init] = useState(() => {
    if (typeof initialState === "function") {
      return (initialState as () => T)();
    }
    return initialState;
  });
  // Set a state to trigger component rendering const [, setState] = useState(init);
  
  // When reading value, the latest value is obtained // When setting value, setState will be triggered and component rendering const [ref] = useState<StateRefObj<T>>(() => {
    return {
      _state: init,
      set value(v: T) {
        this._state = v;
        setState(v);
      },
      get value() {
        return this._state;
      },
    };
  });
  
  // What is returned is a reference variable, which remains unchanged during the entire component life cycle return ref;
}

So, we can use it like this:

const watch = useStateRef('');
const other1 = useStateRef('');
const other2 = useStateRef('');

// Change the value like this: watch.value = "new";

useEffect(() => {
    doSomething(other1.value, other2.value);
   // Actually, these three values ​​are now reference variables, which remain unchanged during the entire component life cycle, so there is no need to add dependency arrays. // However, the eslint plugin of react hooks can only recognize useRef as a reference. If it is not added, it will warn people. For the safety of variable references, it is still added. }, [watch.value, other1, other2]);

In this way, watch, other1 , and other2 have the reference feature of useRef and will not trigger unnecessary execution of doSomething . With the responsiveness of useState , changing .value will trigger component rendering and interface updates.
When we want the variable change to trigger doSomething , we add watch.value to the dependency array. When we just want to reference the value and don't want it to trigger doSomething , we add the variable itself to the array.

The above is the details of the React tips on how to get rid of the troubles of hooks dependency. For more information about React hooks dependency, 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
  • 30 minutes to give you a comprehensive understanding of React Hooks
  • How React Hooks Work
  • React hooks pros and cons
  • React's transition from Class to Hooks

<<:  Analysis of the implementation process of Nginx high availability solution in production environment

>>:  Installation tutorial of mysql 5.7 under CentOS 7

Recommend

How to disable web page styles using Firefox's web developer

Prerequisite: The web developer plugin has been in...

MySQL infobright installation steps

Table of contents 1. Use the "rpm -ivh insta...

MySQL dual-machine hot standby implementation solution [testable]

Table of contents 1. Concept 2. Environmental Des...

Introduction to Docker Quick Deployment of SpringBoot Project

1. Install Docker First open the Linux environmen...

3 ways to correctly modify the maximum number of connections in MySQL

We all know that after the MySQL database is inst...

Analysis of the event loop mechanism of js

Preface As we all know, JavaScript is single-thre...

Javascript design pattern prototype mode details

Table of contents 1. Prototype mode Example 1 Exa...

Mysql accidental deletion of data solution and kill statement principle

mysql accidentally deleted data Using the delete ...

Detailed installation and configuration of hadoop2.7.2 under ubuntu15.10

There are many Hadoop installation tutorials on L...

Summary of English names of Chinese fonts

When using the font-family property in CSS to ref...

Lambda expression principles and examples

Lambda Expressions Lambda expressions, also known...

MySQL 5.7.18 Installer installation download graphic tutorial

This article records the detailed installation tu...

Neon light effects implemented with pure CSS3

This is the effect to be achieved: You can see th...

Why MySQL does not recommend using subqueries and joins

To do a paginated query: 1. For MySQL, it is not ...