Hooks
Since everyone overwhelmingly embraced hooks, we won't bother with class component.
Why is hooks so popular? It's more intuitive, it's concise, and easier to reuse.
Most frequently used built-in hooks are:
- useState: Used to manage state within a functional component.
- useEffect: Used to perform side effects, such as fetching data or add event listeners.
- useRef: Used to create and manage mutable references.
- useCallback: Used to memoize functions, preventing unnecessary re-renders.
- useMemo: Used to memoize calculations, preventing unnecessary recalculations.
the Dependency Array
The most important feature of hooks is perhaps the dependency array. The hook is rerun once dependencies changes.
import React from 'react'
import { useState, useEffect } from 'react'
function MyComponent() {
const [count, setCount] = useState(0)
useEffect(() => {
console.log(`count: ${count}`)
}, [count]) // the dependency array
return <div onClick={() => setCount(count + 1)}>Hooks!</div>
}
Custom Hooks
You can write your own hooks. It's always tempting to do data fetching in a componnet, so we will write a usePromise to help us fetching data.
function usePromise(fn) {
const [state, setState] = useState({pending: true})
useEffect(() => {
fn().then(result => setState({result}), error => setState({error}))
}, []) // why not passing fn as dependency?
return state
}
To use usePromise:
function MyComponent(props) {
const {error, pending, result} = usePromise(() => fetch(props.url).then(x => x.text()), [])
if (error) {
return <div>error occoured</div>
}
if (pending) {
return <div>loading</div>
}
return <div>result</div>
}
What about adding a retry button?
Pitfalls
- Always pass the dependency array, even it's empty.
- Pass the right dependencies.
- All useX() must be called, must not be wrapped in if statements.