hooks api

ZShuai
1 min

# hooks api

https://zh-hans.reactjs.org/docs/hooks-reference.html

# useContext

  • 父组件 Parent.tsx
import { createContext } from "react";
export const FlowContext = createContext<any>(null);

const Parent: React.FC = () => (
  <FlowContext.Provider value={{ name: "lcr" }}>
    {children}
  </FlowContext.Provider>
);

export default Parent;
  • 子组件
import { useContext } from "react";
import { FlowContext } from "@/pages/Parent";

const Child: React.FC = () => {
  const data = useContext(FlowContext);
  return <div>{data.name}</div>;
};

export default Child;

# useCallback

配合 React.memo , 优化组件, 例如如下:

解决: 那就是使用 useCallback 包裹函数:

const callback = useCallback((e: any) => setnum(Math.random()), []);

问题: useCallback 第二个参数,是依赖项, 如果依赖项变化, 那么函数还是会频繁创建, 导致 React.meno 包裹的组件重新渲染. 有什么方法可以保证函数地址一值不变?

官方临时提议,使用 ref, 变量重新缓存 useCallback 需要访问的值,ahooks 中的 usePersistFn(3.x 是 useMemoizedFn ) 就是这种思路实现不需要传递依赖项的, 下面是源码:

type noop = (this: any, ...args: any[]) => any;

type PickFunction<T extends noop> = (
  this: ThisParameterType<T>,
  ...args: Parameters<T>
) => ReturnType<T>;

function useMemoizedFn<T extends noop>(fn: T) {
  const fnRef = useRef<T>(fn);
  fnRef.current = useMemo(() => fn, [fn]);
  const memoizedFn = useRef<PickFunction<T>>();
  if (!memoizedFn.current) {
    memoizedFn.current = function (this, ...args) {
      return fnRef.current.apply(this, args);
    };
  }
  return memoizedFn.current;
}

# useRef

https://zh-hans.reactjs.org/docs/hooks-reference.html#useref

useRef 返回一个可变的 ref 对象,其 .current 属性被初始化为传入的参数(initialValue)。返回的 ref 对象在组件的整个生命周期内持续存在。

一个常见的用例便是命令式地访问子组件, 无论该节点如何改变,React 都会将 ref 对象的 .current 属性设置为相应的 DOM 节点。

import { useRef } from "react";

const ref = useRef<HTMLInputElement>(null);
console.log(ref.current?.value);

<input ref={ref} type="text" />;

请记住,当 ref 对象内容发生变化时,useRef 并不会通知你。变更 .current 属性不会引发组件重新渲染

# useImperativeHandle

  • 使用场景: 父组件访问子组件(函数组件)的某些方法

  • 使用语法: useImperativeHandle(ref, createHandle, [deps]);

  • 具体用法传送门

Last Updated: 2/10/2023, 6:53:47 AM