Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

react useEffect : Outer scope values like 'authService._user' aren't valid dependencies because mutating them doesn't re-render the component

I want to use useEffect to check if user signed in print username on menu. but I get this warning:

React Hook useEffect has an unnecessary dependency: 'authService._user'. Either exclude it or remove the dependency array. Outer scope values like 'authService._user' aren't valid dependencies because mutating them doesn't re-render the component react-hooks/exhaustive-deps

this is my useEffect in navbar:

    useEffect(() => {
    setUsername(authService._user.username);
}, [authService._user])

and this is my authorise service example:

interface User {
username: string;
password: string;
}
export class AuthorizeService {
_user: User = {
    username: '',
    password: ''
};
_isAuthenticated = false;

isAuthenticated() {
    return this._isAuthenticated;
}

Authenticate(username: string, password: string) {
    this._isAuthenticated = true; //I will add fetch latter here
    this._user =  {
        username: username,
        password: password
    }
}
}

const authService = new AuthorizeService();

export default authService;

btw everything work great but there is warning in console.

my question is: is that the right way to do it? and why there is warning.

like image 537
Mehrdad Davoudi Avatar asked May 30 '26 01:05

Mehrdad Davoudi


2 Answers

Minimal reproduction and explanation of the error

I was a bit confused by the error in the middle of a large project, but I understood why it happens and created a minimal example. Consider this minimal Next.js example with a Hoc:

pages/index.js

import React from 'react'

function HomeHoc(msg) {
  return function Home() {
    React.useEffect(() => {
      document.title = msg
    }, [msg])
    return <p>{ msg }</p>
  }
}

export default HomeHoc('asdf')

I had mindlessly added msg to the React.useEffect previously to try and satisfy react-hooks/exhaustive-deps in several places, and then next lint gave me:

7:8 Warning: React Hook React.useEffect has an unnecessary dependency: 'msg'. Either exclude it or remove the dependency array. Outer scope values like 'msg' aren't valid dependencies because mutating them doesn't re-render the component. react-hooks/exhaustive-deps

But clearly, this msg dependency is not necessary, because msg is defined in the HomeHoc scope, and goes to the Home component as a closure. It therefore obviously cannot change once a Home is created.

Therefore, you should just remove msg from the dependency list as suggested by the lint message, as it won't ever make any difference.

The rest of the reproduction setup:

package.json

{
  "name": "with-eslint",
  "version": "1.0.0",
  "scripts": {
    "dev": "next",
    "build": "next build",
    "start": "next start",
    "lint": "next lint"
  },
  "license": "MIT",
  "dependencies": {
    "next": "12.0.7",
    "react": "^17.0.2",
    "react-dom": "^17.0.2"
  },
  "devDependencies": {
    "eslint": "^7.24.0",
    "eslint-config-next": "12.0.7"
  }
}

.eslintrc

{
  "extends": "next",
  "root": true
}

You need to fill that array only if it is coming from props.

Take a look at https://en.reactjs.org/docs/hooks-effect.html in the section "Tip: Optimizing Performance by Skipping Effects"

But I suggest to read the whole docs about useEffects, there are some important details there and its a short documentation.

like image 44
Sheldon Oliveira Avatar answered Jun 02 '26 03:06

Sheldon Oliveira



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!