React Hooks Simplified
[Web Dev Simplified
My name is Kyle and I have been a full stack web developer since 2015. I have a Computer Engineering degree, but am…courses.webdevsimplified.com](https://courses.webdevsimplified.com/view/courses/react-hooks-simplified "courses.webdevsimplified.com/view/courses/r..")
useState
Initial State Computation
useState(() => {
/* Slow computation */
})
Updating State Objects
setPreferences(prevPreferences => {
return { ...prevPreferences, theme: 'dark' }
})
useEffect
useEffect(() => {
console.log('This is my side effect')
return () => {
console.log('This is my clean up')
}
})
// MOUNTED
// This is my side effect
// RE-RENDER 1:
// This is my clean up
// This is my side effect
// RE-RENDER 2:
// This is my clean up
// This is my side effect
// UN-MOUNT:
// This is my clean up
This is because the cleanup is run directly before the side effect is run as long as the side effect has occurred at least once. Also, the cleanup is run when a component un-mounts as well.
useContext
you can put Context inside other Context
useRef
storing the previous value of a state variable
function Component() {
const [name, setName] = useState('Kyle')
const previousName = useRef(null)
useEffect(() => {
previousName.current = name
}, [name])
return (
<>
setName(e.target.value)} />
{previousName.current} => {name}
</>
)
}
useMemo
Referential Equality : comparing objects in dependency arrays
function Component({ param1, param2 }) {
const params = useMemo(() => {
return { param1, param2, param3: 5 }
}, [param1, param2])
useEffect(() => {
callApi(params)
}, [params])
}
the reference for params will only change if param1, or param2 change.
useCallback
Referential Equality : Just like with useMemo, useCallback is used to maintain referential equality.
function Parent() {
const [items, setItems] = useState([])
const handleLoad = useCallback((res) => setItems(res), [])
return
}
function Child({ onLoad }) {
useEffect(() => {
callApi(onLoad)
}, [onLoad])
}
Now the handleLoad function will never change, thus the useEffect in the Child component will not be called on each re-render.
useReducer
const ACTIONS = {
INCREMENT: 'increment',
DECREMENT: 'decrement',
RESET: 'reset',
CHANGE_COUNT: 'change-count'
}
function reducer(count, action) {
switch (action.type) {
case ACTIONS.INCREMENT:
return count + 1
case ACTIONS.DECREMENT:
return count - 1
case ACTIONS.RESET:
return 0
case ACTIONS.CHANGE_COUNT:
return count + action.payload.amount
default:
return count
}
}
function Counter() {
const [count, dispatch] = useReducer(reducer, 0)
return (
<>
{count}
dispatch({ type: ACTIONS.INCREMENT })}>
dispatch({ type: ACTIONS.DECREMENT })}>
{
dispatch({
type: ACTIONS.CHANGE_COUNT,
payload: { amount: 5 }
})
}}>
Add 5
dispatch({ type: ACTIONS.RESET })}>
Reset
</>
)
}