react教程,通过useImperativeHandle暴露函数组件内部函数
发布于 作者:苏南大叔 来源:程序如此灵动~
在前面的forwardRef的相关文章中,苏南大叔曾经说过,可以通过ref访问到类式组件里面的变量以及方法。而同时,并不能使用ref访问到函数式组件里面的变量及方法。

苏南大叔的程序如此灵动博客,记录苏南大叔和计算机代码的故事。本文描述,react项目通过ref访问组件内部函数或变量的方法。特别说明的是,使用useImperativeHandle访问函数式组件的方法。测试环境:create-react-app@5.0.1,react@18.2.0,react-dom@18.2.0,node@16.14.2。
前置阅读项目
下面的两篇文章,可能会对您正确理解本文用例有帮助:

访问类式组件方法和变量(基础对比例子)
访问类式组件内部的方法或者变量,就是顺理成章的事情,只需要对子组件的实例设置了正确的ref即可。
【注意:就是ref字样】import React, { useRef, Component, useEffect } from 'react';
class Sunan1 extends Component {
constructor(props) {
super(props);
this.state = {
count: 0
}
}
var1 = "sunan大叔";
setCount(cnt) {
this.setState((state) => { return { "count": cnt } })
}
increase() {
this.setState((state) => { return { "count": state.count + 1 } })
}
render() {
return (
<div>
<p>【类式子组件,父组件可直接通过ref访问】次数:{this.state.count}</p>
</div>
)
}
}
const App = () => {
const ref = useRef(null);
useEffect(()=>{
console.log(ref.current.var1);
},[])
return <div>
<button onClick={() => ref.current.increase()}>父节点控制函数组件计数加1</button>
<button onClick={() => ref.current.setCount(100)}>重置计数值100</button>
<Sunan1 ref={ref} />
</div>
}
export default App;
访问函数式组件方法和变量(使用场景)
先提出问题:
但是同样的需求,在函数式组件这边却变得异常复杂。首先,函数式组件的实例,不能直接设置ref属性,会有警告信息。除非:
1、使用forwardRef,但是转过的ref就很可能变了指代对象了。
2、不设置ref,换个名字比如ref2,使用props.ref2来获得引用。不过,也有转移指代对象的嫌疑。
再使用useImperativeHandle解决这个问题,范例代码如下:
import React, { useState, useImperativeHandle, useRef, Component, useEffect } from 'react';
const Sunan2 = ({ ref2 }) => {
const [count, setCount] = useState(0)
const var1 = "苏南大叔";
useImperativeHandle(ref2, () => ({
increase, setCount, var1
}))
const increase = () => {
setCount((v) => v + 1)
}
return <div>
<p>【函数子组件,需要useImperativeHandle】次数:{count}</p>
</div>
}
const App = () => {
const ref2 = useRef(null);
useEffect(()=>{
console.log(ref2.current.var1);
},[])
return <div>
<button onClick={() => ref2.current.increase()}>父节点控制函数组件计数加1</button>
<button onClick={() => ref2.current.setCount(100)}>重置计数值100</button>
<Sunan2 ref2={ref2} />
</div>
}
export default App
核心代码:
useImperativeHandle(ref2, () => ({
increase, setCount, var1
}))把要暴露出去的函数或者变量,都放在上面即可,用逗号分割。用起来是不是就和module.exports={}很类似?
另外,在函数式组件里面,通过props传递的ref2引用,最终也没有绑定到某个具体的对象或者元素上。仅仅是和useImperativeHandle产生了联系。
结束语
更多react经验文章,点击下面的链接: