可以將重複的程式邏輯簡化,原理是將重複的狀態快取起來,當元件重新渲染時,使用useMemo儲存的狀態便會偵測是否需要做運算還是從快取拿結果就好
const mediaCategories = useMemo(() => ['popular', 'top_rated'], [])
// 第一個參數為function,代表不需要常常重新執行的事情
// 第二個參數代表依dependencies,當改變時就要執行function,再將function值回傳
const expensiveValue = useMemo(() => {
// Some complex computation based on props
return props.a * props.b;
}, [props.a, props.b]); // Memoize the value with dependencies
也是可以重複使用的function儲存起來,rerender時不會執行,只有改變dependencie才會改變function,和useMemo差別在於useCallback針對function,useMemo針對單一狀態
和useEffect很像,輸入參數為一個function、dependencies array,和useEffect差別在於,他並不會一開始就執行一次,並且這個callback function可以被覆用像是給某個onClick觸發,
const search = useCallback(async () => {
setOnSearch(true)
const { response, error } = await mediaApi.searchMedia({ mediaType, query, page })
setOnSearch(false)
if (error) toast.error(error)
if (response) setMedias(m => [...m, ...response.results])
}, [mediaType, query, page])
可以和useEffect搭配使用,因為使用useCallback確保search不會任意改變,只會在[mediaType, query, page]
改變時觸發search改變進一步觸發useEffect重新執行,這樣有幾個好處。
useEffect(() => {
window.scrollTo(0, 0)
if (query.trim().length === 0) {
setMedias([])
setPage(1)
} else search()
}, [search, query])
一般來說當我要改變count值時只能透過setCount,並且假設你要設置的行為要根據上一個狀態做改變,舉例像是count需要根據上一次count + 1。透過方法二的方式會比較好
const [count,setCount] = useState(0)
setCount(count + 1) // 當前的count + 1
setCount(prevCount => prvCount + 1) // 根據上一次count + 1
假設現在有很多動作會觸發setCount,count不會馬上進行更新,他只夠透過觸發rerender之後count才會更新,也就是說如果同一次rerender之前執行很多方法1最後只會+1,而如果使用方法2就會照常運作。