项目里用的太少了,记录个 demo. useImperativeHandle 可以让你在使用 ref 时自定义暴露给父组件的实例值。 在大多数情况下,应当避免使用 ref 这样的命令式代码。useImperativeHandle 应当与 forwardRef 一起使用。
# 使用步骤
- 定义 ref 初始值 = useRef(initialVal)
- 使用 hook: useImperativeHandle(ref, createHandle, [deps])
- 子组件的 Input 中使用 ref={ref}
- 子组件 export default forwardRef(子组件)
- 父组件定义自己的 refInput = useRef()
- 父组件传递 refInput 给子组件
- 父组件可以通过 refInput.current 拿到子组件暴露的值,也可通过 refInput.current.xx 调用子组件 createHandle 中的其他方法/值
// 子组件
import React, {
ForwardRefRenderFunction,
useImperativeHandle,
forwardRef,
useRef,
} from "react";
interface Props {
name: string;
}
export interface InputExportMethod {
focus: () => void;
domeSomeThing: () => void;
}
const Input: ForwardRefRenderFunction<InputExportMethod, Props> = (
props,
ref
) => {
const inputRef = useRef<HTMLInputElement>(null);
// 子组件方法
const domeSomeThing = () => {
// dosomething
console.log("do smething");
};
useImperativeHandle(
ref,
() => ({
focus: () => inputRef.current?.focus(),
domeSomeThing: () => domeSomeThing(),
}),
[]
);
return (
<div>
<input ref={inputRef}></input>
</div>
);
};
const ExportInput = forwardRef(Input);
export default ExportInput;
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
37
38
39
40
41
42
43
44
45
46
47
48
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
37
38
39
40
41
42
43
44
45
46
47
48
// 父组件
import React, { useEffect, useRef } from "react";
import Input, { InputExportMethod } from "./index";
const Parent: React.FC = () => {
const inputRef = useRef<InputExportMethod>(null);
useEffect(() => {
if (inputRef.current) {
console.log(inputRef.current.domeSomeThing());
}
}, []);
return <Input ref={inputRef} name="19Qingfeng"></Input>;
};
export default Parent;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17