React中refs的一些常見用法匯總
什么是Refs
Refs 提供了一種方式,允許我們訪問 DOM 節(jié)點或在 render 方法中創(chuàng)建的 React 元素。
Ref轉(zhuǎn)發(fā)是一項將ref自動通過組件傳遞到子組件的技巧。 通常用來獲取DOM節(jié)點或者React元素實例的工具。在React中Refs提供了一種方式,允許用戶訪問dom節(jié)點或者在render方法中創(chuàng)建的React元素。
Refs轉(zhuǎn)發(fā)
Ref 轉(zhuǎn)發(fā)是一個可選特性,其允許某些組件接收 ref,并將其向下傳遞(換句話說,“轉(zhuǎn)發(fā)”它)給子組件。
默認(rèn)情況下,不能在函數(shù)組件上使用 ref 屬性,因為它們沒有實例:
一、String 類型的 Refs
不建議使用,因為 string 類型的 refs 存在一些問題。它已過時并可能會在未來的版本被移除。
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ù)的方式定義的,在更新過程中它會被執(zhí)行兩次
- 第一次傳入?yún)?shù) null,然后第二次會傳入?yún)?shù) DOM 元素
- 這是因為在每次渲染時會創(chuàng)建一個新的函數(shù)實例,所以 React 清空舊的 ref 并且設(shè)置新的
- 通過將 ref 的回調(diào)函數(shù)定義成 class 的綁定函數(shù)的方式可以避免上述問題
- 但是大多數(shù)情況下它是無關(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 屬性,因為它們沒有實例
- 如果要在函數(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 時自定義暴露給父組件的實例值 useImperativeHandle(ref, () => { return { reload: reload, }; }); return <div ref={ref}>ForwardRefFunc {name}</div>; }); const ForwardRefFunc = React.memo(RefFunc);
forwardRef 和 useImperativeHandle 最終目的是設(shè)法給 ref 提供一個可調(diào)用的對象!
總結(jié)
到此這篇關(guān)于React中refs的一些常見用法的文章就介紹到這了,更多相關(guān)React中refs用法內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
react中useEffect函數(shù)的詳細(xì)用法(最新推薦)
useEffect是React中的一個Hook,用于在函數(shù)組件中處理副作用(如數(shù)據(jù)獲取、訂閱、手動更改 DOM 等),useEffect屬于組件的生命周期方法,下面通過本文給大家分享react中useEffect函數(shù)的詳細(xì)用法,感興趣的朋友跟隨小編一起看看吧2024-06-06React Native中TabBarIOS的簡單使用方法示例
最近在學(xué)習(xí)過程中遇到了很多問題,TabBarIOS的使用就是一個,所以下面這篇文章主要給大家介紹了關(guān)于React Native中TabBarIOS簡單使用的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),需要的朋友可以參考下。2017-10-10React系列useSyncExternalStore學(xué)習(xí)詳解
這篇文章主要為大家介紹了React系列useSyncExternalStore的學(xué)習(xí)及示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2022-07-07淺析history 和 react-router 的實現(xiàn)原理
react-router 版本更新非???但是它的底層實現(xiàn)原理確是萬變不離其中,在本文中會從前端路由出發(fā)到 react-router 原理總結(jié)與分享,本文對history 和 react-router實現(xiàn)原理講解的非常詳細(xì),需要的朋友跟隨小編一起看看吧2023-08-08