父组件通过props将一个回调函数传递给子组件。子组件可以在需要的时候调用回调函数,将数据传递给父组件。但是,这种方法是在子组件里触发的,有没有在父组件里触发的方法。
有,子组件暴露方法给父组件,让父组件手动调用。
是一个非常经典的 “子组件暴露方法给父组件” 的场景,这在 React 中是完全可以实现的,关键是使用 forwardRef
和 useImperativeHandle
这两个 Hook 组合。
子组件(暴露方法)
// Child.js
import React, { forwardRef, useImperativeHandle } from "react";
const Child = forwardRef((props, ref) => {
const sayHello = () => {
alert("子组件的方法被父组件调用了");
};
useImperativeHandle(ref, () => ({
sayHello,
// 你可以暴露多个方法,比如:
doSomething: () => console.log("Doing something..."),
}));
return <div>我是子组件</div>;
});
export default Child;
-
forwardRef
:允许父组件通过ref
获取子组件内部能力。 -
useImperativeHandle
:用它来“暴露”方法给父组件。
父组件(调用子组件方法)
// Parent.js
import React, { useRef } from "react";
import Child from "./Child";
const Parent = () => {
const childRef = useRef();
const handleClick = () => {
childRef.current.sayHello(); // 调用子组件方法
};
return (
<div>
<button onClick={handleClick}>调用子组件方法</button>
<Child ref={childRef} />
</div>
);
};
export default Parent;
注意事项
-
这个技巧一般用于:
-
控制子组件的内部行为(比如:打开弹窗、滚动、聚焦输入框等)
-
手动触发验证、提交等行为
-
-
不建议乱用,最好保持数据流是从上到下的。
常规的 props 回调
父组件(传回调函数)
// Parent.js
import React from "react";
import Child from "./Child";
const Parent = () => {
const handleReceiveData = (msg) => {
alert("父组件收到的数据:" + msg);
};
return (
<div>
<h2>父组件</h2>
<Child onSend={handleReceiveData} />
</div>
);
};
export default Parent;
子组件(内部触发)
// Child.js
import React from "react";
const Child = ({ onSend }) => {
const handleClick = () => {
onSend("你好,我是子组件发来的消息!");
};
return (
<div>
<h3>子组件</h3>
<button onClick={handleClick}>点击发送消息给父组件</button>
</div>
);
};
export default Child;
执行流程:
-
父组件传了一个
handleReceiveData
给子组件。 -
子组件点击按钮时执行
onSend(...)
。 -
这个函数其实就是父组件的函数 → 于是数据就“上送”了。
方式 | 说明 | 示例 |
---|---|---|
子组件调用父组件函数 | 常规 props 回调 | onSend(msg) |
父组件调用子组件方法 | forwardRef + useImperativeHandle | childRef.current.xxx() |