Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why eslint-plugin-react-hooks doesn't warn when using react hooks conditionally?

Tags:

reactjs

eslint

I'm using react 16.8, and eslint-plugin-react-hooks 1.6.0 .When I use hooks conditionally, I hoped eslint was going to warn me. Here is my config :

"eslintConfig": {
    "parser": "babel-eslint",
    "plugins": [
      "react-hooks"
    ],
    "rules": {
      "react-hooks/rules-of-hooks": "error",
      "react-hooks/exhaustive-deps": "warn"
    }
}

If I use hooks conditionally in custom hooks, there will be a warning like this: "React Hook \"useState\" is called conditionally. React Hooks must be called in the exact same order in every component render."

function useCustomHook() {
  if (Math.random() > 0.5){
    const [a, setA] = useState(0)
  }
}

but if I use hooks in function component, it does't work.

function MyComponent() {
  if (Math.random() > 0.5){
    const [a, setA] = useState(0)
  }
  return null
}
like image 323
junting liu Avatar asked Apr 28 '19 15:04

junting liu


People also ask

Can we call React Hooks conditionally?

React basically knows which useEffect hook is which, basically by counting invocations. Calling useEffect conditionally is bad, specifically because the amount of times useEffect gets called cannot change. Your example is conditional, but React can't detect it because in either condition you call it once.

What is the purpose of ESLint plugin for Hooks?

This ESLint plugin enforces the Rules of Hooks. It is a part of the Hooks API for React.

What is the practice to avoid when using React Hooks?

Hooks should not be called within loops, conditions, or nested functions since conditionally executed Hooks can cause unexpected bugs. Avoiding such situations ensures that Hooks are called in the correct order each time the component renders.


2 Answers

This is what worked for me:

  1. First install the appropriate eslint plugin:
   $ npm i --save-dev eslint-plugin-react-hooks
  1. Add it into your .eslintrc together with default config:
  {
    "plugins": [
      ...
      "react-hooks"
    ],
    "rules": {
      ...
      "react-hooks/rules-of-hooks": "error",
      "react-hooks/exhaustive-deps": "warn"
    }
    ...
  1. Install the eslint configuration template "react-app":
  $ npm i --save-dev eslint-config-react-app
  1. In your .eslintrc extend from the newly installed configuration:
  {
    ...
    "extends": "react-app"
  1. Make sure you have the proper peer dependencies of the new package, e.g. I had to do:
  $ npm i --save-dev eslint-plugin-flowtype
  1. Make sure your eslint package is version 5+ e.g. 5.16.0 works, higher should also work (but beware that higher eslint also requires newer nodejs).
  $ npm i --save-dev eslint@^5.0.0
  1. Restart VSCode
  2. Press Cmd-Shift-U to open the output terminal, switch to Eslint in the dropdown menu and check that it loaded without errors.
like image 148
Darko Maksimovic Avatar answered Oct 23 '22 19:10

Darko Maksimovic


Actually, when I paste your function on the App.js file created by create-react-app, there is the expected error when running the app.

Maybe your function isn't considered a React Component (your function is considered a common function). Make sure you have React on scope (import React from "react";)

like image 30
Murilo Cruz Avatar answered Oct 23 '22 19:10

Murilo Cruz