While I was learning React while in The Flatiron School’s Software Engineering bootcamp I learned about creating components by using class components only. We learned about some lifecycle methods in general and state was to be managed with a constructor. Once we were encouraged to check out functional components and useState to manage our state I enjoyed the look and feel of this style of React.

Using functional components and useState amongst the other react Hooks make the code look much cleaner and easier to understand. I have been using useState and useEffect in my recent projects and I have enjoyed using them. I want to dig deeper into the full lifecycle and become familiar all of the Hooks to become a more experienced React developer. In this blog I will be covering The 3 most common hooks in detail and a brief introduction to the other 7.

What is a Hook?

To learn more about Hooks we should start with the definition. The official react documentation says, “Hooks are functions that let you “hook into” React state and lifecycle features from function components. Hooks don’t work inside classes — they let you use React without classes.” Hooks are functions that are prepended buy the “use”.

Rules of Hooks

  1. Only call Hooks at the top level
  2. Only use Hooks in functional components
  3. You cannot call Hooks from regular JavaScript functions they must be React functions.
  4. Node version 6 or above
  5. NPM version 5.2 or above
  6. Import all appropriate hooks you plan to use at the top of a component.
import { useState } from 'react';

What are the Hooks available?

There are currently 10 hooks available as well as custom hooks.

  • useState
  • useEffect
  • useContext
  • useReducer
  • useCallback
  • useMemo
  • useRef
  • useImperativeHandle
  • useLayoutEffect
  • useDebugValue

useState()

The most important and often used hook. The purpose is to handle reactive data in the form of state. When a change is made to state you want it to update throughout the component. UseState takes 1 optional argument which is the default state. UseState returns an array of 2 values. The first value is the reactive value of the state and the second is the setter in which you call to change the state when necessary. These are local variables that can be named anything but the setter must be prepended by “set”.

[name, setName] = useState("programmer") 
//name in state will default to programmer
const eventToChangeName = () => {
setName("Adam")
}
//name will be Adam after function is called

useEffect()

useEffect is one of the more confusing Hooks. To understand useEffect you must understand the React component lifecycle, which I will likely do a blog on soon. A simple refresher of lifcycle methods are componentDidMount(), componentDidUpdate(), componentWillUnmount(). UseEffect allows us to handle these lifecycle methods in one function. UseEffect takes it’s first argumet as a function you define. This will run once when mounted then every time state changes. An issue I have run into with this in my own projects has been doing a fetch request inside useEffect to set state asynchronously. The fetch will run then set state. After that is completed state will be updated and the componentDidUpdate() role of useEffect will run again, creating an infinite loop. To avoid this useEffect takes a second argument which is an array of dependencies. If you pass in an empty array it will run once. If you add state in tyhe array of dependencies it will run every time thaty state is updated.

useEffect(() => {
eventToChangeName()
}, [])

useContext()

UseContext allows us to work with React’s context API which shared data throughout the entire component tree without passing props. You can create a context and call it from useContext to use in a component on a different level than the one you are on.

cont pets = {
bobo: 'Cat' ,
lucy: 'Dog'
}
const PetContext = createContext(pets);function App(props) {
return(
<PetContext.Provider value={pets.bobo}>
<FindTheAnimal /> </PetContext.Provider>
)
}
function FindTheAnimal = () => {
const animal = useContext(PetContext)
return (
<p> animal </p>
)
}

useRef()

UseRef allows you to create a mutable object that will keep the same reference between renders. This is used when you want to store a value like useState but do not want to trigger a re-render of the page. A common use for useRef is to grab HTML elements from the DOM.

function App() {   const myButton = useRef(null)   const click = () => myButton.current.click()   return(
<button ref={myButton}> </button>
)
}

useReducer()

useReducer is a state management hook that manages state in a different way. This Hook is used in Redux to dispatch actions to the store. The useReducer function takes in an argument of a reducer you are using and returns an array of the state and the dispatch. It can also take a second argument of a default value of the state. Using the Redux pattern and useReducer is helpful in a large app whith many components to manage state.

useMemo()

UseMemo is used to optimize computation and improve performance. You can use this when you know there is something hurting performance. Like useEffect, you can set a dependency to determine when these computations take place.

const [counter, setCounter] = useState(2)const expensiveCount = useMemo(() => {
return count ** 2
}, count)

This function only will take place when count changes to avoid happening every re-render. This will memoize a return value. If you want to memoize an entire function you would use the next Hook.

useCallback()

When you define a function in a component a new function object is created on render. This is slow when passing the same function down to multiple children components. Wrapping the function in useCallback will increase performance rendering the same thing multiple times.

useImperativeHandle()

If you build a reusable React library un react you may need to a native DOM element. This hook comes in if you want to change the behavior of that ref.

useLayoutEffect()

This is just like useEffect but with one difference. It will run but before updates have been rendered. React will wait for the code to run before it updates you the user.

useDebugValue()

Use useDebugValue inside custom hooks to see the name of the Hooks inside dev tools along with the Hooks involved to create the custom Hook.