React父组件如何触发子组件函数
const ModalContent: React.FC<{
ref:any;
sourceId?: any;
}> = forwardRef(({ sourceId, ...props }, ref) => {}
forwardRef
forwardRef
允许组件使用 ref 将 DOM 节点暴露给父组件。
forwardRef(render)
使用 forwardRef()
让组件接收 ref 并将其传递给子组件:
import { forwardRef } from 'react';
const MyInput = forwardRef(function MyInput(props, ref) {
// ...
});
参数
render
:组件的渲染函数。React 会调用该函数并传入父组件传递的 props 和ref
。返回的 JSX 将作为组件的输出。
返回值
forwardRef
返回一个可以在 JSX 中渲染的 React 组件。与作为纯函数定义的 React 组件不同,forwardRef
返回的组件还能够接收 ref
属性。
render
函数
forwardRef
接受一个渲染函数作为参数。React 将会使用 props
和 ref
调用此函数:
const MyInput = forwardRef(function MyInput(props, ref) {
return (
<label>
{props.label}
<input ref={ref} />
</label>
);
});
参数
props
:父组件传递过来的 props。ref
:父组件传递的ref
属性。ref
可以是一个对象或函数。如果父组件没有传递一个 ref,那么它将会是null
。你应该将接收到的ref
转发给另一个组件,或者将其传递给useImperativeHandle
。
返回值
forwardRef
返回一个可以在 JSX 中渲染的 React 组件。与作为纯函数定义的 React 组件不同,forwardRef
返回的组件还能够接收 ref
属性。
将 DOM 节点暴露给父组件
默认情况下,每个组件的 DOM 节点都是私有的。然而,有时候将 DOM 节点公开给父组件是很有用的,比如允许对它进行聚焦。将组件定义包装在 forwardRef()
中便可以公开 DOM 节点:
import { forwardRef } from 'react';
const MyInput = forwardRef(function MyInput(props, ref) {
const { label, ...otherProps } = props;
return (
<label>
{label}
<input {...otherProps} />
</label>
);
});
你将在 props 之后收到一个 ref 作为第二个参数。将其传递到要公开的 DOM 节点中:
import { forwardRef } from 'react';
const MyInput = forwardRef(function MyInput(props, ref) {
const { label, ...otherProps } = props;
return (
<label>
{label}
<input {...otherProps} ref={ref} />
</label>
);
});
这样,父级的 Form
组件就能够访问 MyInput
暴露的 <input>
DOM 节点:
function Form() {
const ref = useRef(null);
function handleClick() {
ref.current.focus();
}
return (
<form>
<MyInput label="Enter your name:" ref={ref} />
<button type="button" onClick={handleClick}>
编辑
</button>
</form>
);
}
useImperativeHandle
useImperativeHandle
是 React 中的一个 Hook,它能让你自定义由 ref 暴露出来的句柄。
useImperativeHandle(ref, createHandle, dependencies?)
useImperativeHandle
的第一个参数是父组件传递给子组件的ref
,第二个参数是一个回调函数,用于定义要暴露给父组件的方法或属性。这个回调函数可以接收一个依赖项数组作为第三个参数,当依赖项发生变化时,会重新调用回调函数。
子组件
const handleCollapseAll = () => {
setExpandedRowKeys([]);
};
useImperativeHandle(ref, () => ({
handleCollapseAll
}), []);
父组件
<Modal
title="库存清单"
open={modalVisible}
onCancel={() => {
expandRef.current?.handleCollapseAll();//引用方式
setModalVisible(false)
}}
footer={null}
className="list"
width={1000}
style={{ width: '1000px', height: '700px', maxWidth: '100%', top: 10 }}
>
<ModalContent ref={expandRef} sourceId={sourceId} />
</Modal>