JIYIK CN >

Current Location:Home > Learning > WEB FRONT-END > React >

Understanding the detailed Eslint rules in React

Author:JIYIK Last Updated:2025/03/16 Views:

The "react-hooks/exhaustive-deps" rule warns us when we are missing dependencies in effect hooks. To get rid of the warning, move the function or variable declaration useEffectinside the hook, remember arrays and objects that change on each render, or disable the rule.

Here is an example of how this can result in a warning.

import React, {useEffect, useState} from 'react';

export default function App() {
  const [address, setAddress] = useState({country: '', city: ''});

  // 👇️ objects/arrays 不同于 re-renders
  // 它们是通过引用进行比较的 
  const obj = {country: 'China', city: 'Beijing'};

  useEffect(() => {
    setAddress(obj);
    console.log('useEffect called');

    // ⛔️ React Hook useEffect has a missing dependency: 'obj'.
    // Either include it or remove the dependency array. eslintreact-hooks/exhaustive-deps
  }, []);

  return (
    <div>
      <h1>Country: {address.country}</h1>
      <h1>City: {address.city}</h1>
    </div>
  );
}

The problem is that we useEffectare using the obj variable in the hook, but we haven't included it in the dependencies array.

The most obvious solution to this error is to add the obj variable to the dependencies array of the useEffect hook.

However, in this case it will cause an error because objects and arrays are compared by reference in JavaScript.

The obj variable is an object with the same key-value pairs on every re-render, but it points to a different location in memory each time, so it causes the equality check to fail and leads to an infinite re-render loop.

In JavaScript, arrays are also compared by reference.

One way to bypass the warning "React Hook useEffect has a missing dependency" is to disable the eslint rule for a single line or the whole file.

import React, {useEffect, useState} from 'react';

export default function App() {
  const [address, setAddress] = useState({country: '', city: ''});

  // 👇️ objects/arrays 不同于 re-renders
  const obj = {country: 'Germany', city: 'Hamburg'};

  useEffect(() => {
    setAddress(obj);
    console.log('useEffect called');

    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, []);

  return (
    <div>
      <h1>Country: {address.country}</h1>
      <h1>City: {address.city}</h1>
    </div>
  );
}

The comment above the dependencies array disables the react-hooks/exhausting-deps rule for a single line.

When the useEffect hook is passed an empty array as the second argument, it is called only when the component mounts.

Another solution is to move the variable or function declaration inside the useEffect hook.

import React, {useEffect, useState} from 'react';

export default function App() {
  const [address, setAddress] = useState({country: '', city: ''});

  useEffect(() => {
    // 👇️ 在 useEffect 钩子内移动对象/数组/函数声明
    const obj = {country: 'Germany', city: 'Hamburg'};

    setAddress(obj);
    console.log('useEffect called');
  }, []);

  return (
    <div>
      <h1>Country: {address.country}</h1>
      <h1>City: {address.city}</h1>
    </div>
  );
}

We moved the variable declaration of the object into the useEffect hook.

This eliminates the warning, since the hook no longer depends on an external object.

Another possible solution, rarely used but good to know, is to move the function or variable declaration out of the component.

import React, {useEffect, useState} from 'react';

// 👇️ 将函数/变量声明移到组件之外
const obj = {country: 'Germany', city: 'Hamburg'};

export default function App() {
  const [address, setAddress] = useState({country: '', city: ''});

  useEffect(() => {
    setAddress(obj);
    console.log('useEffect called');
  }, []);

  return (
    <div>
      <h1>Country: {address.country}</h1>
      <h1>City: {address.city}</h1>
    </div>
  );
}

This helps because the variables are not recreated every time the App component is re-rendered.

This variable will point to the same place in memory across all renders, so useEffect doesn't need to track it in its dependencies array.

Another solution is to use the useMemo hook to get the memoized value.

import React, {useMemo, useEffect, useState} from 'react';

export default function App() {
  const [address, setAddress] = useState({country: '', city: ''});

  // 👇️ 获取记住的值
  const obj = useMemo(() => {
    return {country: 'Germany', city: 'Hamburg'};
  }, []);

  useEffect(() => {
    setAddress(obj);
    console.log('useEffect called');

    // 👇️ 安全地包含在依赖项数组中
  }, [obj]);

  return (
    <div>
      <h1>Country: {address.country}</h1>
      <h1>City: {address.city}</h1>
    </div>
  );
}

We use the useMemo hook to get a memoized value that doesn't change between renders.

The useMemo hook accepts a function that returns a value to memoize and an array of dependencies as arguments. The hook will only recalculate the memoized value if one of the dependencies has changed.

If you're using a function, you can use the useCallback hook to get a memoized callback that doesn't change between renders.

import React, {useMemo, useEffect, useState, useCallback} from 'react';

export default function App() {
  const [address, setAddress] = useState({country: '', city: ''});

  // 👇️ 获取记住的回调函数
  const sum = useCallback((a, b) => {
    return a + b;
  }, []);

  // 👇️ 获取记住的值
  const obj = useMemo(() => {
    return {country: 'Germany', city: 'Santiago'};
  }, []);

  useEffect(() => {
    setAddress(obj);
    console.log('useEffect called');

    console.log(sum(100, 100));

    // 👇️ 安全地包含在依赖项数组中
  }, [obj, sum]);

  return (
    <div>
      <h1>Country: {address.country}</h1>
      <h1>City: {address.city}</h1>
    </div>
  );
}

The useCallback hook takes an inline callback function and an array of dependencies and returns a memoized version of the callback that only changes if one of the dependencies changes.

If none of the suggestions apply to our use case, we can always hide the warnings via comments.

import React, {useEffect, useState} from 'react';

export default function App() {
  const [address, setAddress] = useState({country: '', city: ''});

  const obj = {country: 'Chile', city: 'Santiago'};

  useEffect(() => {
    setAddress(obj);
    console.log('useEffect called');

  // 👇️ 禁用单行规则

  // eslint-disable-next-line react-hooks/exhaustive-deps
  }, []);

  return (
    <div>
      <h1>Country: {address.country}</h1>
      <h1>City: {address.city}</h1>
    </div>
  );
}

For reprinting, please send an email to 1244347461@qq.com for approval. After obtaining the author's consent, kindly include the source as a link.

Article URL:

Related Articles

React Tutorial - Transferring Props

Publish Date:2025/03/16 Views:185 Category:React

React transfers Props. Props are generated when components are encapsulated. Components expose some properties (Props) to the outside world to complete some functions.

React Tutorial: Props Anti-Pattern

Publish Date:2025/03/16 Views:183 Category:React

React's Props anti-pattern, using Props to generate state in getInitialState is an anti-pattern - Anti-Pattern.

React Tutorial - Props Validation

Publish Date:2025/03/16 Views:99 Category:React

Props validation is a very useful way to use components correctly. It can avoid many bugs and problems as your application becomes more and more complex. In addition, it can make your program more readable.

Why do you need to bind event handlers in React Class Components?

Publish Date:2025/03/16 Views:58 Category:React

When using React, we must have come across control components and event handlers. We need to use `.bind()` in the constructor of the custom component to bind these methods to the component instance. As shown in the following code:

Solution to the error "does not contain a default export" in React

Publish Date:2025/03/16 Views:187 Category:React

When we try to use `default import` to import from a module that does not have a `default export`, we get a "does not contain a default export" error. To fix the error, make sure the module has named exports and wrap the import in curly braces, e.g.

Solve the Module not found: Can't resolve 'react-bootstrap' error

Publish Date:2025/03/16 Views:85 Category:React

To resolve the error "Module not found: Error: Can't resolve 'react-bootstrap'", make sure to install the react-bootstrap package by opening a terminal in the root directory of the project and running the command `npm install react-bootstrap bootstrap

Scan to Read All Tech Tutorials

Social Media
  • https://www.github.com/onmpw
  • qq:1244347461

Recommended

Tags

Scan the Code
Easier Access Tutorial