React中refs的一些常見用法匯總
什么是Refs
Refs 提供了一種方式,允許我們?cè)L問 DOM 節(jié)點(diǎn)或在 render 方法中創(chuàng)建的 React 元素。
Ref轉(zhuǎn)發(fā)是一項(xiàng)將ref自動(dòng)通過(guò)組件傳遞到子組件的技巧。 通常用來(lái)獲取DOM節(jié)點(diǎn)或者React元素實(shí)例的工具。在React中Refs提供了一種方式,允許用戶訪問dom節(jié)點(diǎn)或者在render方法中創(chuàng)建的React元素。
Refs轉(zhuǎn)發(fā)
Ref 轉(zhuǎn)發(fā)是一個(gè)可選特性,其允許某些組件接收 ref,并將其向下傳遞(換句話說(shuō),“轉(zhuǎn)發(fā)”它)給子組件。
默認(rèn)情況下,不能在函數(shù)組件上使用 ref 屬性,因?yàn)樗鼈儧]有實(shí)例:
一、String 類型的 Refs
不建議使用,因?yàn)?string 類型的 refs 存在一些問題。它已過(guò)時(shí)并可能會(huì)在未來(lái)的版本被移除。
import React from "react";
// 父組件
export default class StringRef extends React.PureComponent {
componentDidMount() {
console.log("stringRefDom:", this.refs.stringRefDom);
console.log("stringRefComp:", this.refs.stringRefComp);
}
render() {
return (
<div>
{/*原生組件使用方式*/}
<div ref={"stringRefDom"}>stringRefDom</div>
{/*類組件使用方式*/}
<StringRefComp ref={"stringRefComp"} />
</div>
);
}
}
//類組件
class StringRefComp extends React.PureComponent {
render() {
return <div>StringRefComp</div>;
}
}
二、回調(diào) Refs
- 如果 ref 回調(diào)函數(shù)是以內(nèi)聯(lián)函數(shù)的方式定義的,在更新過(guò)程中它會(huì)被執(zhí)行兩次
- 第一次傳入?yún)?shù) null,然后第二次會(huì)傳入?yún)?shù) DOM 元素
- 這是因?yàn)樵诿看武秩緯r(shí)會(huì)創(chuàng)建一個(gè)新的函數(shù)實(shí)例,所以 React 清空舊的 ref 并且設(shè)置新的
- 通過(guò)將 ref 的回調(diào)函數(shù)定義成 class 的綁定函數(shù)的方式可以避免上述問題
- 但是大多數(shù)情況下它是無(wú)關(guān)緊要的
import React from "react";
// 父組件
export default class CallbackRef extends React.PureComponent {
constructor(props) {
super(props);
this.callbackRefDom = null;
this.callbackRefComp = null;
}
componentDidMount() {
console.log("callbackRefDom:", this.callbackRefDom);
console.log("callbackRefComp:", this.callbackRefComp);
}
//回調(diào)函數(shù)
setCallbackRefDom = (ref) => {
this.callbackRefDom = ref;
};
setCallbackRefComp = (ref) => {
this.callbackRefComp = ref;
};
//回調(diào)函數(shù)
render() {
return (
<div>
<div ref={this.setCallbackRefDom}>callbackRefDom</div>
<CallbackRefComp ref={this.setCallbackRefComp} />
</div>
);
}
}
//類組件
class CallbackRefComp extends React.PureComponent {
render() {
return <div>callbackRefComp</div>;
}
}
三、React.createRef()
- React 16.3 版本引入
- 較早版本的 React,推薦使用回調(diào)形式的 refs
import React from "react";
// 父組件
export default class CreateRef extends React.PureComponent {
constructor(props) {
super(props);
this.createRefDom = React.createRef();
this.createRefComp = React.createRef();
}
componentDidMount() {
console.log("createRefDom:", this.createRefDom.current);
console.log("createRefComp:", this.createRefComp.current);
}
render() {
return (
<div>
<div ref={this.createRefDom}>createRefDom</div>
<CreateRefComp ref={this.createRefComp} />
</div>
);
}
}
//類組件
class CreateRefComp extends React.PureComponent {
render() {
return <div>CreateRefComp</div>;
}
}
四、useRef
- Hook 是 React 16.8 的新增特性
import React, { useEffect } from "react";
// 父組件
const UseRef = React.memo(() => {
// // 同樣可以用
// const createRefDom = React.createRef();
// const createRefComp = React.createRef();
const createRefDom = React.useRef();
const createRefComp = React.useRef();
useEffect(() => {
console.log("useRefDom:", createRefDom.current);
console.log("useRefComp:", createRefComp.current);
}, []);
return (
<div>
<div ref={createRefDom}>useRefDom</div>
<UseRefComp ref={createRefComp} />
</div>
);
});
export default UseRef;
//類組件
class UseRefComp extends React.PureComponent {
render() {
return <div>useRefComp</div>;
}
}
五、Refs 與函數(shù)組件
- 默認(rèn)情況下,你不能在函數(shù)組件上使用 ref 屬性,因?yàn)樗鼈儧]有實(shí)例
- 如果要在函數(shù)組件中使用 ref,你可以使用 forwardRef(可與 useImperativeHandle 結(jié)合使用)
- 或者將該組件轉(zhuǎn)化為 class 組件。
import React, { useEffect, useImperativeHandle } from "react";
// 父組件
const ForwardRef = React.memo(() => {
const createRefComp = React.useRef();
const createRefCompMethod = React.useRef();
useEffect(() => {
console.log("useRefComp:", createRefComp.current);
console.log("createRefCompMethod:", createRefCompMethod.current);
createRefComp.current.reload();
}, []);
return (
<div>
<ForwardRefFunc ref={createRefComp} />
</div>
);
});
export default ForwardRef;
const RefFunc = React.forwardRef((props, ref) => {
const [name, setName] = React.useState(null);
const reload = () => {
console.log("reload");
setTimeout(() => {
setName("ForwardRefFunc");
}, 3000);
};
//useImperativeHandle 可以讓你在使用 ref 時(shí)自定義暴露給父組件的實(shí)例值
useImperativeHandle(ref, () => {
return {
reload: reload,
};
});
return <div ref={ref}>ForwardRefFunc {name}</div>;
});
const ForwardRefFunc = React.memo(RefFunc);
forwardRef 和 useImperativeHandle 最終目的是設(shè)法給 ref 提供一個(gè)可調(diào)用的對(duì)象!
總結(jié)
到此這篇關(guān)于React中refs的一些常見用法的文章就介紹到這了,更多相關(guān)React中refs用法內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
react中useEffect函數(shù)的詳細(xì)用法(最新推薦)
useEffect是React中的一個(gè)Hook,用于在函數(shù)組件中處理副作用(如數(shù)據(jù)獲取、訂閱、手動(dòng)更改 DOM 等),useEffect屬于組件的生命周期方法,下面通過(guò)本文給大家分享react中useEffect函數(shù)的詳細(xì)用法,感興趣的朋友跟隨小編一起看看吧2024-06-06
ahooks控制時(shí)機(jī)的hook實(shí)現(xiàn)方法
這篇文章主要為大家介紹了ahooks控制時(shí)機(jī)的hook實(shí)現(xiàn)方法示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-07-07
React Native中TabBarIOS的簡(jiǎn)單使用方法示例
最近在學(xué)習(xí)過(guò)程中遇到了很多問題,TabBarIOS的使用就是一個(gè),所以下面這篇文章主要給大家介紹了關(guān)于React Native中TabBarIOS簡(jiǎn)單使用的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),需要的朋友可以參考下。2017-10-10
React系列useSyncExternalStore學(xué)習(xí)詳解
這篇文章主要為大家介紹了React系列useSyncExternalStore的學(xué)習(xí)及示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-07-07
淺析history 和 react-router 的實(shí)現(xiàn)原理
react-router 版本更新非???但是它的底層實(shí)現(xiàn)原理確是萬(wàn)變不離其中,在本文中會(huì)從前端路由出發(fā)到 react-router 原理總結(jié)與分享,本文對(duì)history 和 react-router實(shí)現(xiàn)原理講解的非常詳細(xì),需要的朋友跟隨小編一起看看吧2023-08-08

