「譯」React.useRef 和 React.createRef 的異同

大家好,我是做工程師不做碼農!聚焦大前端技術和程序員成長的乾貨公眾號,點擊關注,每天給你精彩!

「譯」React.useRef 和 React.createRef 的異同

相關閱讀:


兩個React API均用於創建可變對象。可變對象的屬性可以隨意更改,而不會影響組件的狀態。

這個對象有一個 current 屬性,這個屬性是存儲值和引用的地方。

這些 API 創建了可稱為 refs 的可變對象。它們包含我們想要的任何值的引用。

在類組件中使用 React.createRef 來創建引用。

<code>class App extends React.Component {
componentDidMount() {
this.divRef = React.createRef()
}
render() {
return (

App, here


)
}
}/<code>

在這裡,在divRef中創建一個引用。我們將其作為值分配給 render 方法中 div#divR 元素中的 ref 屬性。

這將創建 div#divR 的DOM實例,並將其分配給 divRef。可以從 divRef 中的 current 屬性引用DOM實例。

<code>divRef.current instanceof HTMLDivElement
true/<code>

在函數組件中,我們使用 React.useRef:

<code>function App {
const divRef = React.useRef()
return (

App, here


)
}/<code>

與類組件版本中的效果相同。useRef 將在 divRef 中創建一個引用。使用 div#divR 中的 ref 屬性,我們將把 div#divR 的DOM實例分配給 divRef。要從divRef獲取DOM實例,我們引用其 current 屬性即可。

createRef 和 useRef 可以用來存儲任何值,而不僅僅是通過 ref

來存儲DOM實例。

<code>function App {
const divRef = React.useRef()
const valueRef = React.useRef(90)
return (

Value: {valueRef.current}
App, here

<button> valueRef.current = 88}>Incr/<button>

)
}/<code>

valueRef是一個在其 current 屬性中保留值為90的 ref。我們通過引用JSX大括號中的current來在render方法中顯示valueRef值。當組件渲染時,我們將看到90。

更改ref的值不會重新渲染組件。看看Incr按鈕,單擊該按鈕會將valueRef值更改為88,這不會重新渲染組件。因此,我們仍然會在DOM中看到90(valueRef的舊值)。這意味著,我們需要在組件中觸發重新渲染以查看valueRef的當前值。

<code>function App {
const divRef = React.useRef()
const valueRef = React.useRef(90)
const [,setDummyState] = useState()
return (

Value: {valueRef.current}
App, here

<button> (valueRef.current = 88, setDummyState({}))}>Incr/<button>

)

}/<code>

我們創建了一個虛假(dummy)狀態和一個 summy 函數來觸發組件中的重新渲染。現在,單擊Incr將重新渲染組件,我們將在valueRef中看到更新後的值反映在DOM中。

我們已經看到了它們的用途,它們是一樣的。我們只能在類組件中使用createRef,只能在函數組件中使用useRef。

在函數組件中使用createRef不會引發任何錯誤,但是會導致不一致。例如,如果我們將上述功能應用程序更改為使用createRef:

<code>function App {
const valueRef = React.createRef()
const [,setDummyState] = useState()
return (

Value: {valueRef.current}
<button> (valueRef.current = 88, setDummyState({}))}>Incr/<button>

)
}/<code>

無論我們點擊多少次Incr按鈕,我們的值總是null。valueRef 被更新為88,功能應用程序被重新渲染。

這是因為函數組件是函數,它們重新渲染或渲染仍然像正常函數一樣運行它們。

<code>App()
let props = {
name: "nnamdi",

age: 90
}
App(props)/<code>

問題在於函數組件返回的JSX將由React在瀏覽器DOM中渲染。

現在,當函數 App 被重新渲染時,函數將運行,這將重新初始化並在其主體中重新創建所有表達式和語句。因此,createRef將每次運行,並且值始終為null。

這就是為什麼創建useRef hook來在函數組件的整個生命週期中維護ref current 值的原因,在re-render上重新運行函數不會重新創建ref值。

createRef在類組件中效果很好,因為重新渲染組件僅調用render方法,shouldComponent和componentDidMount方法。

<code>// mounting
const appInstance = new App(props, context)
// constructor is called and ref is created
appInstance.componentWillMount()
appInstance.componentDidMount()
// re-rendering
if(appInstance.shouldComponentUpdate())
appInstance.componentWillMount()
appInstance.componentDidMount()/<code>

它不會重新實例化類,所以ref值在類組件的整個生命週期內都是一致的。

為了確保在組件的整個生命週期中都保持引用值,請在構造方法中創建它們。


原文:https://blog.bitsrc.io/react-useref-and-react-createref-the-difference-afedb9877d0f

翻譯:做工程不做碼農


分享到:


相關文章: