refs
作用
1.获取子组件的元素的dom
2.获取子组件的数据
获取子组件的元素的dom步骤
- 我们通过调用
React.createRef
或者 useRef 创建了一个ref 并将其赋值给ref
变量。 - 我们通过指定
ref
为 JSX 属性,将其向下传递给<Compoment ref={ref}>
。 - React 传递
ref
给forwardRef
内函数(props, ref) => ...
,作为其第二个参数。 - 我们向下转发该
ref
参数到<button ref={ref}>
,将其指定为 JSX 属性。 - 当 ref 挂载完成,
ref.current
将指向<button>
DOM 节点。
使用实例
父组件中创建ref,并传递给子组件
const Parent = React.forwardRef((props, ref) => {
// 创建ref实例
const authRef = useRef<any>();
render() {
return (
// 使用-----------------------------------------------------------------------------
// 在传递ref给子组件
<Component ref={authRef} />
)
})
子组件中接受使用ref,作用于button元素上
const Component = React.forwardRef((props, ref) => {
render() {
return (
<button ref={ref}>
{props.children}
</button>
)
}
})
export default Component
父组件获取子组件dom
const Component = React.forwardRef((props, ref) => {
// 创建ref实例
const authRef = useRef<any>();
const handle = () => {
// 使用
authRef.xxxx
}
render() {
return (
// 使用-----------------------------------------------------------------------------
// 在传递ref给子组件
<Component ref={authRef} />
)
})
获取子组件的数据
- 我们通过调用
React.createRef
或者 useRef 创建了一个ref 并将其赋值给ref
变量。 - 我们通过指定
ref
为 JSX 属性,将其向下传递给<Compoment ref={ref}>
。 - React 传递
ref
给forwardRef
内函数(props, ref) => ...
,作为其第二个参数。 - 使用useImperativeHandle暴露数据
获取全部数据
父组件,与上例的父组件基本一致基本
const Parent = React.forwardRef((props, ref) => {
// 创建ref实例
const authRef = useRef<any>();
render() {
return (
// 使用-----------------------------------------------------------------------------
// 在传递ref给子组件
<Component ref={authRef} />
)
})
子组件
const Component = React.forwardRef((props, ref) => {
const [data, setData] = useState('data')
// 暴露数据
useImperativeHandle(ref, () => ({
getData: () => {
return data;
},
}));
render() {
<div>这是子组件</div>
}
})
export default Component
父组件获取数据
const Parent = React.forwardRef((props, ref) => {
// 创建ref实例
const authRef = useRef<any>();
const handle = () => {
console.log(authRef.current.getData())
}
render() {
return (
// 使用-----------------------------------------------------------------------------
// 在传递ref给子组件
<Component ref={authRef} />
)
})
在高阶组件使用refs
需要注意的是,高阶组件是不会透传ref,这是因为 ref
不是 prop 属性。就像 key
一样,其被 React 进行了特殊处理。如果你对 HOC 添加 ref,该 ref 将引用最外层的容器组件,而不是被包裹的组件。
但是,可以使用 React.forwardRef
API 明确地将 refs 转发到内部的 组件。React.forwardRef
接受一个渲染函数,其接收 props
和 ref
参数并返回一个 React 节
上面的获取数据的例子来说,如果使用到redux的话,connect返回的是一个高阶函数,生成的是高阶组件,所以直接给Component使用React.forwardRef是不起作用的,起作用的是高阶组件
修改子组件如下即可正常使用
const Component = ({refInstance}) => {
const [data, setData] = useState('data')
// 暴露数据
useImperativeHandle(refInstance, () => ({
getData: () => {
return data;
},
}));
render() {
<div>这是子组件</div>
}
}
const COM = connect(
({ userInfoStore }) => ({
userInfoStore,
}),
)(Component);
interface inter {
refInstance?: any;
}
// 使用Hoc 透传 ref 为 refInstance
export default React.forwardRef((props: inter, ref) => {
return (
<COM
{...props}
refInstance={ref}
/>
);
});