Featured image of post React-Hooks 指南

React-Hooks 指南

React Hooks 含义

为函数组件提供钩子以实现外部功能,如添加状态

React 默认提供的四个最常用的钩子

1
2
3
4
5
useState()  //状态

useEffect()    //函数副作用
useContext()
useReducer()

更多的 Hook包括

1
2
3
4
5
6
7
8
useReducer
useCallback
useMemo
useRef
useImperativeHandle
useLayoutEffect
useDebugValue
自定义Hook

useImperativeHandle

Typescript中搭配useImperativeHandle 和 forwardRef使用

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
export interface MyInputHandles {
  focus(): void;
}

const MyInput: RefForwardingComponent<MyInputHandles, MyInputProps> = (
  props,
  ref
) => {
  const inputRef = useRef<HTMLInputElement>(null);

  useImperativeHandle(ref, () => ({
    focus: () => {
      if (inputRef.current) {
        inputRef.current.focus();
      }
    },
  }));

  return <input {...props} ref={inputRef} />;
};

export default forwardRef(MyInput);

建议useImperativeHandle和forwardRef同时使用,减少暴露给父组件的属性,避免使用 ref 这样的命令式代码 import { useRef,forwardRef,MutableRefObject,useImperativeHandle,Ref} from “react”;

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
//只暴露value、getType、focus给父级
const InputEl = forwardRef((props: {}, ref: Ref<any>): JSX.Element=>{
    const inputEl: MutableRefObject<any> = useRef();

    useImperativeHandle(ref, ()=>({//第一个参数:暴露哪个ref;第二个参数:暴露什么
        value: (inputEl.current as HTMLInputElement).value,
        getType: () => (inputEl.current as HTMLInputElement).type,
        focus: () => (inputEl.current as HTMLInputElement).focus()
    }));

    return(
        <input ref={inputEl} type="text" {...props}/>
    )
})
//暴露整个input节点给父级
const InputEl = forwardRef((props: {}, ref: Ref<any>): JSX.Element=>{
    return(
        <input ref={ref} type="text" {...props}/>
    )
});

//父级
function InputWithFocusButton() {
    const inputEl: MutableRefObject<any> = useRef(null);

    function onButtonClick() {
        console.log('子组件input的对象:', inputEl.current);
        inputEl.current.focus();
    };
    return (
        <>
            <InputEl ref={inputEl} />
            <button onClick={onButtonClick}>Focus the input</button>
        </>
    );
}

复制代码通过forwardRef,父组件获取子组件的ref,子组件在暴露ref中,限制暴露的一些参数

*自定义hooks,封装重复使用的代码,可以抽离出成一个模块,在多个场景下使用,提高代码的复用性

参考:
React Hook 最佳实践 https://blog.csdn.net/weixin_43902189/article/details/99689963
React 文档
useEffect完全指南 video React Hook FAQ