文章目录
react 中类组件与函数组件 ref 的使用
1、先来看函数组件:
目标:普通元素就获取元素DOM
组件就获取组件的实例
1、普通元素:
const Index = () => {
const inputRef = useRef(null)
const getData = () => {
console.log(inputRef.current.value);
}
return (
<div className="search">
<input type="text" placeholder="请输入" ref={inputRef}/>
<button onClick={getData}>添加</button>
</div>
)
}
export default Index
2、通过 Ref 获取组件实列调用方法:
// 父组件
import React, { useRef } from "react"
import './App.css'
import Index from "./Index.jsx"
const App = () => {
const IndexRef = useRef(null)
return (
<div className="search">
<button onClick={() => {
IndexRef.current.getData()
}}>获取子组件的实列</button>
<Index ref={IndexRef}/>
</div>
)
}
export default App
// 子组件
import React, { useImperativeHandle, forwardRef } from "react";
const Index = forwardRef((props,ref) => {
useImperativeHandle(ref, () => ({
getData
}));
const getData = () => {
console.log('打印了Index 组件');
}
return (
<button onClick={getData}>子组件Index</button>
)
})
export default Index
上图可以看出,父组件通过 Ref 调用子组件身上的 方法
2、useRef 突破函数组件的特性:
目标:能够使用 useRef hook 在组件更新期间维持一个值
useRef hook
有以下特点:
1、 useRef 有一个 current 属性,可以通过该属性存储任意值
, 组件重新渲染不会重置 current的值
const Index = () => {
console.log('Index组件重新 执行');
const [count ,setCount] = useState(0)
const params = useRef({})
// 存储值
const setData = () => {
params.current = {
status:0
}
console.log('设置data为', params.current);
// 更新状态,让组件重新渲染
setCount(count + 1)
}
// 取值
const gainData = () => {
console.log('获取data为', params.current);
}
return (
<div>
<button onClick={setData}>设置值</button>
<button onClick={gainData}>获取值</button>
</div>
)
}
export default Index
从上图可以看出 Index 组件执行了两次,通过 setCount 更新状态,但我们的current 输出的值还是上一次存储的
2、 修改 useRef current 的值不会导致组件重新渲
从图片可以看出修改了 current 的值,但组件 Index 只执行了一次
3、类组件使用 Ref :
上图可以看出父组件使用 Ref 调用子组件身上的 方法
4、总结:
函数组件因为没有 实列所以使用 Ref 调用子组件方法的时候 得配合 useImperativeHandle 与 forwardRef 一起使用
函数组件 useRef hook 可以操作 Dom 可以用 current 来存储值,并且组件重新执行,current 存储的值还在 ,修改current的值不会导致组件重新执行
类组件有实列直接创建 Ref 使用即可