React logo

There a few basic rules we need to follow when using hooks

1. Call Hooks at the Top Level:

Hooks must be immediately after declaring the function and keep in mind they are called in the order they are declared. Never call hooks inside a loop, condition, or nested functions since you may disrupt the order in which they are called, and by doing this you will end up with errors such infinity renders which will use up the memory of your browser and cause the application to crash, or you will end up with undefined object, or other errors.

function Example() {
   const [address, setAddress] = useState('myStreet');

   if (address !== '') {  
      //this breaks the first rule by using a Hook inside an if statement
      useEffect(function persistForm() {
         localStorage.setItem('formData', address);
      });
   }

   const [addressNumber, setAddressNumber] = useState('123');

   useEffect(function updateAddress() {
      props.setUserAddress = address + ' ' + addressNumber;
   });
}

Any constant declared and not initialized in a function such as address in the example above will evaluate this condition address!== ''  as true on the first render. During next renders some other functions could change the initial constant value, resulting on the previous condition evaluating to false and therefore skipping this Hook during rendering, and in turn changing the order of the hooks are called.

useState('myStreet')           // 1. Read the address state
useEffect(persistForm)         //  address !== ' ' is false so is not executed
useState('123')                // 2. (but was 3). Fail to read the addressNumber state
useEffect(updateAddress)       // 3. (but was 4). Fail to replace the effect

Therefore, if we want to run an effect conditionally we must write the condition inside of the hook.

2. Don’t use hooks from a React class component or JavaScript functions

As the title says, do not call a hook from a class component or javascript function. Here below you can find two samples of bad practices and the errors they generate

//JavaScript

const [name, setName] = useState('')
useffect(()=>{
  setName('Steve')
},[])

useffect(()=>{
   document.querySelector('#header').innerHTML = name + ' ' + surname
},[surname])


-----------------------------------------------------------
 // Returns: ReferenceError: useState is not defined
    at <anonymous>:2:23
    at hn (https://preview-javascript.playcode.io/:207:5449)
//Class Components

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

export default class Example extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
 
    };
  }
  const [name, setName] = useState("");

  useEffect(() => {
    setName(props.name);
  }, [props.name]);

  return (
    <>
      <h1>Hello {name}</h1>
    </>
  );
};

--------------------------------------------------
//Returns: /src/example.js: Unexpected token (10:8)

   8 |     };
   9 |   }
> 10 |   const [name, setName] = useState("");
     |         ^
  11 |
  12 |   useEffect(() => {
  13 |     setName(props.name);