Skip to content
On this page

useImperativeHandle

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

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

JavaScript
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>;
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

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

JavaScript
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>;
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

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

JavaScript
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>;
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
沪ICP备20006251号-1