useImperativeHandle

useImperativeHandle 和 ref 转发

useImperativeHandle 可以让你在使用 ref 时自定义暴露给父组件的实例值,应当与 forwardRef 一起使用,实现 ref 转发

我们获取类组件实例后,可以直接调用实例上的方法!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import React, { useEffect, useRef } from "react";
class Child extends React.Component {
submit = () => {
console.log("调用了子组件的submit方法!");
};
render() {
return <div>           ...        </div>;
}
}
export default function Demo() {
const box = useRef(null);
useEffect(() => {
console.log(box.current); //子组件的实例
box.current.submit();
}, []);
return (
<div>
       <Child ref={box} />   
</div>
);
}

但是直接把 ref 赋值给函数组件,是不被允许的!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
const Child = function () {
return <div>       ...    </div>;
};
export default function Demo() {
const box = useRef(null);
useEffect(() => {
console.log(box.current); //null // Warning: Function components cannot be given refs. Attempts to access this ref will fail. Did you mean to use React.forwardRef()?
}, []);
return (
<div>
       <Child ref={box} />   
</div>
);
}

此时我们可以基于 forwardRef 和 useImperativeHandle , 就可以实现父组件调用子组件中的方法!

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
import React, {
useEffect,
useRef,
useImperativeHandle,
forwardRef,
} from "react";
const Child = forwardRef(function (props, ref) {
useImperativeHandle(ref, () => {
return {
submit: () => {
console.log("调用了子组件的submit方法!");
},
};
});
return <div>       ...    </div>;
});
export default function Demo() {
const box = useRef(null);
useEffect(() => {
console.log(box.current);
box.current.submit();
}, []);
return (
<div>
       <Child ref={box} />   
</div>
);
}

useImperativeHandle
https://hugtyftg.github.io/2023/06/21/useImperativeHandle/
作者
mmy@hugtyftg
发布于
2023年6月21日
许可协议