useEffect, useMemo & useCallback
These next three hooks are relatively similar, and fairly simple, so this lesson should go quick.
useEffect
Lets take a look at the type definition for **useEffect**.
This type definition tells us three things:
**useEffect**takes a function, called EffectCallback, as it's first parameter.
- EffectCallback has to return either
**void**, or a cleanup function. That cleanup function has to return**void**.
**useEffect**can optionally take a list of dependencies, which is just an array of**any**.
The only thing to keep in mind when using **useEffect** in TypeScript is that the EffectCallback has to return **void**, which means it returns nothing, or a cleanup function. If we do return a cleanup function, it can't return anything either.
This only really becomes a problem if we are using an implicit return with an arrow function, like this:
Usually it's best to use the non-implicitly returning form of arrow functions with **useEffect**.
It's also worth noting that the seldom-used **useLayoutEffect** hook has exactly the same type definition as **useEffect**.
useMemo
Since it's short, we'll also look at the type definition for **useMemo**:
function useMemo<T>(factory: () => T, deps: DependencyList): T;
**useMemo** is a generic function. We pass it a function, and whatever that function returns is the return value of **useMemo**. I've never had a situation where TypeScript didn't properly infer the value of **T** based on what I passed in, so you'll likely never have to assign a type to **T**
The only thing to note here is that the dependency list for **useMemo** is not optional - you are required to provide one. Otherwise, what's the point of using **useMemo**? Without a dependency list, the value returned from **useMemo** will be referentially different between renders.
useCallback
**useCallback** is just like **useMemo**, except it only memoizes functions for us. Here's the type definition for **useCallback**:
This is mostly the same as **useMemo** except the generic type that represents the return value is constrained to be a function. That's because **useCallback** is specifically used for memoizing functions, so naturally we have to pass a function in.
Like **useMemo**, we also must provide a dependency list. Otherwise, we'll get a warning. It's just TypeScripts way of trying to help you out.