「译」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

翻译:做工程不做码农


分享到:


相關文章: