Add Linting to Help Enforce Rules when Using React Hooks

Elijah Manor
InstructorElijah Manor

Share this video with your friends

Send Tweet
Published 5 years ago
Updated 5 years ago

In order to use Hooks there are a certain set of rules you need to follow. Thankfully, the React Team has provided an ESLint Plugin that will help enforce these rules when using Hooks.

Instructor: [00:00] Here we have an app, bootstrap by Create React App. In order to modify this configuration, we'll need to eject the project so that we can add React's ESLint custom hooks plugin. To do this, run NPM run eject and respond with a Y to declare that you know what you're doing. Keep in mind there isn't an easy way to undo this outside of Git trickery.

[00:26] If you aren't using Create React App, then you probably have full access to control your ESLint settings. Now that we have ejected, let's open up our code editor. Inside of code we'll open up the integrated terminal and install the custom hooks plugin from NPM with NPM I ESLint dash plugin dash React dash hooks. We'll install the next dis tag since it's still prereleased.

[00:53] You may have your ESLint config somewhere else such as at your root in an ESLint RSC file, but Create React App uses the package.json file for its configuration. Here you'll find an ESLint config section and you can add a plugins array containing React dash hooks.

[01:11] Also add a rules object with a key of React dash hooks slash rules dash of dash hooks with the value of error. Now let's take these new rules for a spin. We'll open up the playground.js file and so far so good. No errors yet.

[01:29] Before we make some errors, let's remove some code to make things more clear. There are two main rules when using hooks, one of which is to only call hooks at the top level like we're doing on line four with use state.

[01:43] However, if we were to call a hook inside a condition for example on only Mondays and have a special state defaulting to false, that isn't top level and we'll get an ESLint error. React hook use state is called conditionally. React hooks must be called in the exact same order in every component render.

[02:06] In a similar but different way, let's introduce a new to dos array with values one, two, and three. We'll map over them inside our unordered list. For each item we'll render a list item with the to do value. Let's introduce a new count state hook starting at zero. We'll pin the count to the item and on each on click we'll increment the value.

[02:34] We have an error here too. The error says, "React hook use state cannot be called inside a callback." This error is out for two separate reasons. One, it's not used at the root level. It's used inside of a map, which is basically a loop. The second rule is that hooks must only be called from a React function, either React function component or custom hook.

[02:57] We haven't talked about custom hooks just yet, but they're basically just a special function that starts with use and this special type of function can use React hooks without error. Creating a don't do this function that creates nope state would be an error since don't do this doesn't start with use.

[03:18] If we attempted to start our dev server at this point, it'll fail because we marked these ESLint rules as errors. The output from Create React App also shows these errors in the browser to show the problems at hand. There's currently an issue with Create React App to add support for the ESLint hooks plugin, so in the future you shouldn't need to eject your app when that's supported.

Gonzalo Pozzo
Gonzalo Pozzo
~ 5 years ago

It's really necessary to eject for configuring ESLint? I always used my own config in CRA using an eslintrc.js file without having to eject

Elijah Manor
Elijah Manorinstructor
~ 5 years ago

Gonzalo,

Yes, you can add your own local eslintrc file, but it won't be used in the dev server or build system. A local eslintrc file will only apply to your IDE (Code, vim, etc...).

If you want create-react-app to know about your custom rules you need to eject. You can see some of the background here https://github.com/facebook/create-react-app/issues/808#issuecomment-252941815

Gonzalo Pozzo
Gonzalo Pozzo
~ 5 years ago

Great!, thanks

Robert Reed
Robert Reed
~ 5 years ago

It appears you can now add react-hooks linting rules without ejecting.

Installing react, react-dom, react-scripts, and eslint-plugin-react-hooks all with @next and providing the eslintConfig in the package.json as shown provides the expected behavior.

Elijah Manor
Elijah Manorinstructor
~ 5 years ago

Robert, version 3.0 of create-react-app just came out https://github.com/facebook/create-react-app/releases/tag/v3.0.0 and it now supports the react hooks ESLint rules out-of-the-box... so ejecting isn't needed anymore. I was waiting for this release before re-recording this lesson. I didn't like having to eject because that is messy and makes upgrading harder. Thanks for watching!

Michael Friedman
Michael Friedman
~ 5 years ago

Maybe delete this clip now, no longer relevant.

Elijah Manor
Elijah Manorinstructor
~ 5 years ago

Michael, yeah... now that it's supported in CRA I plan to redo this video and instead focus on what value the lint rules provide (also including the exhaustive-deps rule). Thanks for the feedback!