具体的使用范例,可以参考官方API:Refs转发,本人也是看了官方API以后自己所学习理解领悟的给记录一下,如果有不正确的地方,可以在文章下方的评论区参与评论,然后指正出来!欢迎各位来评论吧!
refs是用来绑定元素的,一定要注意:React中的props是无法传递ref的,ref实际上并不是props,他就像key一样,是专门处理的;使用非常简单,见下列代码吧:
import React from 'react'
import { Button } from 'antd'
function Myrefs() {
const ref = React.createRef() //创建ref
return (
//绑定ref
)
}
以上代码就实现了ref的绑定,通过调用ref.current就能够获取到button这个元素了;现在有一种业务场景,父组件想要获取子组件中的元素,并且改变子组件的值,应该怎么处理呢?具体看下列代码:
// ChildComp.tsx
import React from 'react'
class LogProps extends React.Component {
componentDidUpdate(prevProps) {
console.log('old props:', prevProps)
console.log('new props:', this.props)
}
render() {
const { forwardedRef, ...rest } = this.props
// 将自定义的 prop 属性 “forwardedRef” 定义为 ref
return ChildComp
}
}
// 注意 React.forwardRef 回调的第二个参数 “ref”。
// 我们可以将其作为常规 prop 属性传递给 LogProps,例如 “forwardedRef”
// 然后它就可以被挂载到被 LogPros 包裹的子组件上。
export default React.forwardRef((props, ref) => {
return
})
// Myrefs.tsx 这个就是父组件对应的
import React from 'react'
import { Button } from 'antd'
import ChildComp from './ChildComp'
function Myrefs() {
// 你可以直接获取 DOM button 的 ref:
const ref = React.createRef()
const handleClick = () => {
// 父组件访问到了子组件
ref.current.innerHTML = '父组件通过Ref去改变子组件的值!'
}
return (
<>
>
)
}
export default Myrefs
在上面的代码片段中,点击Button这按钮,就可以通过ref.current获取到了子组件,进而去更改子组件DOM节点的内容;
关于父组件如何将ref传递给子组件,其实很简单的,通过React.forwardRef很容易就实现了。
如果是高阶组件呢?在高阶组件中应该去如何应用呢?请看下列代码,是从官方API中弄过来的:
function logProps(Component) {
class LogProps extends React.Component {
componentDidUpdate(prevProps) {
console.log('old props:', prevProps);
console.log('new props:', this.props);
}
render() {
const {forwardedRef, ...rest} = this.props;
// 将自定义的 prop 属性 “forwardedRef” 定义为 ref
return ;
}
}
// 注意 React.forwardRef 回调的第二个参数 “ref”。
// 我们可以将其作为常规 prop 属性传递给 LogProps,例如 “forwardedRef”
// 然后它就可以被挂载到被 LogProps 包裹的子组件上。
return React.forwardRef((props, ref) => {
return ;
});
}
在本次开发中,有一个业务场景,需要父组件获取子组件的state,当是就是用forwardRef这个给解决的,下面分享一下我的代码:
A组件为父组件,下面嵌套了子组件B组件,现在我要在A组件中获取B组件的值,以此为业务场景首先看A组件:
// A.tsx文件
import React from 'react'
import { Button } from 'antd'
import B from './B'
function A() {
let ref = null
const getCont = () => {
// 在A组件中就获取到了B组价的treeData
const treeData = ref && ref.value()
console.log(treeData)
// 在A组件中就获取到了B组价的selectItem
const selectObj = ref && ref.selectItem()
console.log(selectObj)
}
return (
<>
这个是A组件
{ref = data}} />
>
)
}
export default A
新建子组件B
// B.tsx文件
import React, { forwardRef, useImperativeHandle, useState, useEffect } from 'react'
import { Tree } from 'antd'
function B(props, ref) {
const [ treeData, setTree ] = useState([])
const [ selectItem, setSelect ] = useState([])
useImperativeHandle(ref, () => ({
value:() => {
return treeData
},
selectItem:() => {
return selectItem
}
}))
useEffect(() => {
const init = [
{
"id":1,
"pid":null,
"key":1,
"title":"1-1111",
"children":[
{
"id":2,
"pid":1,
"key":2,
"title":"2-1111",
"children":[
{
"id":4,
"pid":2,
"key":4,
"title":"8-1111",
"children":[
]
}
]
},
{
"id":3,
"pid":1,
"key":3,
"title":"9-1111",
"children":[
]
}
]
}
]
setTree(init)
}, [])
const handleSelect = (selectedKeys) => {
setSelect(selectedKeys)
}
return (
<>
这个是B组件
>
)
}
export default forwardRef(B)
看一下页面实现的效果以及控制台的效果
以上的就是本次分享,完毕了呀!欢迎小伙伴们在下方评论参与讨论呀!