React中Ref的作用小結(jié)
一、Ref的基礎(chǔ)概念
Ref是React提供的一個(gè)接口,允許我們?cè)L問(wèn)在渲染過(guò)程中創(chuàng)建的DOM節(jié)點(diǎn)或組件實(shí)例。它通常用于需要直接操作DOM或訪(fǎng)問(wèn)組件內(nèi)部狀態(tài)的情況。值得注意的是,Ref并不屬于React的數(shù)據(jù)流的一部分,因此它的變更不會(huì)觸發(fā)組件的重新渲染。
二、Ref的使用方式
createRef方法
React 16.3引入了createRef方法,它允許我們創(chuàng)建一個(gè)可變的Ref對(duì)象,并將其賦值給一個(gè)類(lèi)屬性。這個(gè)Ref對(duì)象有一個(gè)current屬性,該屬性指向被引用的DOM節(jié)點(diǎn)或組件實(shí)例。
class MyComponent extends React.Component {
constructor(props) {
super(props);
this.myInputRef = React.createRef();
}
focusInput = () => {
this.myInputRef.current.focus();
};
render() {
return (
<div>
<input type="text" ref={this.myInputRef} />
<button onClick={this.focusInput}>聚焦輸入框</button>
</div>
);
}
}函數(shù)組件中的useRef
在函數(shù)組件中,由于它們沒(méi)有實(shí)例,因此不能直接使用this.refs來(lái)訪(fǎng)問(wèn)Ref。但是,React提供了useRef鉤子,它允許我們?cè)诤瘮?shù)組件中創(chuàng)建和使用Ref。
import React, { useRef } from 'react';
const MyFunctionComponent = () => {
const inputRef = useRef(null);
const focusInput = () => {
if (inputRef.current) {
inputRef.current.focus();
}
};
return (
<div>
<input type="text" ref={inputRef} />
<button onClick={focusInput}>聚焦輸入框</button>
</div>
);
};回調(diào)函數(shù)Ref
回調(diào)函數(shù)Ref是一種更為靈活和推薦的使用方式。通過(guò)提供一個(gè)回調(diào)函數(shù),我們可以在Ref被設(shè)置或更新時(shí)執(zhí)行自定義邏輯。
class MyComponent extends React.Component {
constructor(props) {
super(props);
this.myInputRef = null;
}
setMyInputRef = (element) => {
this.myInputRef = element;
};
focusInput = () => {
if (this.myInputRef) {
this.myInputRef.focus();
}
};
render() {
return (
<div>
<input type="text" ref={this.setMyInputRef} />
<button onClick={this.focusInput}>聚焦輸入框</button>
</div>
);
}
}三、ref操作值但組件不更新的問(wèn)題
在 React 中,組件的更新通常是由狀態(tài)(state)或?qū)傩裕╬rops)的變化觸發(fā)的。當(dāng)使用ref直接操作組件的值時(shí),React 并不知道這個(gè)值已經(jīng)改變了,因?yàn)閞ef繞過(guò)了 React 的響應(yīng)式更新機(jī)制。React 的更新機(jī)制是基于虛擬 DOM 的比較,只有當(dāng)state或props發(fā)生變化時(shí),React 才會(huì)重新渲染組件。
在函數(shù)組件中,我們通常使用React的useState和useRef鉤子來(lái)管理狀態(tài)和引用,與類(lèi)組件類(lèi)似,直接通過(guò)Ref修改狀態(tài)通常不會(huì)觸發(fā)組件的重新渲染。這是因?yàn)镽ef主要用于直接訪(fǎng)問(wèn)DOM元素或組件實(shí)例,而不是用于管理狀態(tài)。
舉例
import React, { useState, useRef } from 'react';
const SimpleInputComponent = () => {
const [inputValue, setInputValue] = useState(0); // React狀態(tài)
const inputRef = useRef(0); // DOM引用
// 處理輸入框變化,更新React狀態(tài)
const handleInputChange = (event) => {
setInputValue(event.target.value);
};
// 直接通過(guò)Ref修改DOM值(不推薦)
const forceUpdateDOMValue = () => {
if (inputRef.current) {
inputRef.current.value = 1;
// 注意:這里雖然DOM值變了,但React狀態(tài)inputValue沒(méi)有變
}
};
// 通過(guò)useState更新?tīng)顟B(tài)(推薦)
const updateStateValue = () => {
setInputValue(2);
};
return (
<div>
<input
type="text"
value={inputValue} // 這里綁定的是React狀態(tài)
onChange={handleInputChange} // 更改時(shí)會(huì)更新React狀態(tài)
ref={inputRef} // 綁定DOM引用
/>
<button onClick={forceUpdateDOMValue}>通過(guò)Ref直接修改DOM值</button>
<button onClick={updateStateValue}>通過(guò)useState更新?tīng)顟B(tài)</button>
<p>當(dāng)前React狀態(tài)值:{inputValue}</p>
</div>
);
};
export default SimpleInputComponent;在這個(gè)例子中,我們有一個(gè)輸入框和兩個(gè)按鈕。當(dāng)你輸入文字時(shí),React狀態(tài)inputValue會(huì)更新,并且組件會(huì)重新渲染以反映新的狀態(tài)。然而,當(dāng)你點(diǎn)擊“通過(guò)Ref直接修改DOM值”按鈕時(shí),雖然輸入框的DOM值被改變了,但React狀態(tài)inputValue并沒(méi)有改變,因此頁(yè)面上顯示的React狀態(tài)值不會(huì)更新。相反,當(dāng)你點(diǎn)擊“通過(guò)useState更新?tīng)顟B(tài)”按鈕時(shí),React狀態(tài)inputValue會(huì)被更新,并且組件會(huì)重新渲染以顯示新的狀態(tài)值。
到此這篇關(guān)于React中Ref的作用小結(jié)的文章就介紹到這了,更多相關(guān)React Ref內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
從零開(kāi)始搭建webpack+react開(kāi)發(fā)環(huán)境的詳細(xì)步驟
這篇文章主要介紹了從零開(kāi)始搭建webpack+react開(kāi)發(fā)環(huán)境的詳細(xì)步驟,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-05-05
React跨端動(dòng)態(tài)化之從JS引擎到RN落地詳解
這篇文章主要為大家介紹了React跨端動(dòng)態(tài)化之從JS引擎到RN落地,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-09-09
react中使用redux-persist做持久化儲(chǔ)存的過(guò)程記錄
這篇文章主要介紹了react中使用redux-persist做持久化儲(chǔ)存的相關(guān)資料,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2024-01-01
React路由的history對(duì)象的插件history的使用解讀
這篇文章主要介紹了React路由的history對(duì)象的插件history的使用,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-10-10
深入理解React調(diào)度(Scheduler)原理
本文主要介紹了深入理解React調(diào)度(Scheduler)原理,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2022-07-07
解決React報(bào)錯(cuò)useNavigate()?may?be?used?only?in?context?of
這篇文章主要為大家介紹了解決React報(bào)錯(cuò)useNavigate()?may?be?used?only?in?context?of?Router,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-12-12
React 使用recharts實(shí)現(xiàn)散點(diǎn)地圖的示例代碼
這篇文章主要介紹了React 使用recharts實(shí)現(xiàn)散點(diǎn)地圖的示例代碼,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-12-12
詳解react使用react-bootstrap當(dāng)輪子造車(chē)
本篇文章主要介紹了詳解react使用react-bootstrap當(dāng)輪子造車(chē),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下。2017-08-08
React?hook實(shí)現(xiàn)簡(jiǎn)單的websocket封裝方式
這篇文章主要介紹了React?hook實(shí)現(xiàn)簡(jiǎn)單的websocket封裝方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-09-09

