由於這兩個 api 的做用是同樣的,因此我放在一塊兒講;vue
語法:react
function useMemo<T>(factory: () => T, deps: DependencyList | undefined): T; function useCallback<T extends (...args: any[]) => any>(callback: T, deps: DependencyList): T;
區別在於第一個參數,還有參數的傳遞,另外 useCallback 中 DependencyList 是一個必須值redux
這兩個 api 的做用基本就是緩存數據/方法api
使用過 react 的人都知道,在組件傳遞值的時候,若是 props 中某一值對象引用發生變化,就會發生從新渲染,即便先後2個對象是徹底相同的;瀏覽器
這2個參數就是爲了解決這個問題,另外也有能夠減輕一些方法的rerender的速度;緩存
做用基本是取代 class 中的 createRef,在此很少細說dom
做用基本是取代 class 中的 Context 中 Context.Provider ,接受參數 Context,由於可能會有多層 context,因此這個參數是必須的,否則沒法辨別ide
語法:函數
function useImperativeHandle<T, R extends T>(ref: Ref<T>|undefined, init: () => R, deps?: DependencyList): void;
官網是叫 useImperativeMethods
,可是我在 @types/react@17.8.7
中,是叫作 useImperativeHandle
的,不過函數名仍是以實際爲準佈局
在官網中,他的做用是這樣解釋的:
useImperativeMethods自定義使用ref時公開給父組件的實例值。 與往常同樣,在大多數狀況下應避免使用refs的命令式代碼。
這個 api 的使用一定伴隨着 forwardRef 這個 api, 使用率基本較低;
官方例子:
function FancyInput(props, ref) { const inputRef = useRef(); useImperativeMethods(ref, () => ({ focus: () => { inputRef.current.focus(); } })); return <input ref={inputRef} />; } FancyInput = forwardRef(FancyInput);
在此示例中,呈現
的父組件將可以調用fancyInputRef.current.focus()。
簡單的說就是講子組件中的建立方法暴露給父組件
簽名與useEffect相同,但在更新兄弟組件以前,它在React執行其DOM突變的同一階段同步觸發。 使用它來執行自定義DOM突變。
一樣的 @types/react@16.8.7 沒有這個函數的聲明;
不過官網中 大可能是告誡儘可能少用此函數
語法:
function useLayoutEffect(effect: EffectCallback, deps?: DependencyList): void;
參數基本和 useEffect
相同
官方所說的效果:
簽名與useEffect相同,但在全部DOM突變後它會同步觸發。 使用它從DOM讀取佈局並同步從新渲染。 在瀏覽器有機會繪製以前,將在useLayoutEffect內部計劃的更新將同步刷新。
不知道你們有沒有使用過 vue,他的做用和 vue 中的 nexttick 差很少吧;
在須要讀取 dom 的高度,寬度的時候特別須要
說到如今, api 基本已經講完了,除了 useReducer, 我將會放在 redux 篇中講述