国外做健康的网站,自己做个网站怎么赚钱,昵图网素材图库大图免费,深圳保障性住房和安居房的区别useRef 是 React 中常用的 Hook 之一#xff0c;它返回一个可变的 ref 对象#xff0c;其 .current 属性被初始化为传入的参数#xff08;initialValue#xff09;。返回的 ref 对象在组件的整个生命周期内保持不变。
以下是一些使用 useRef 的场景和示例#xff1a;
1、…useRef 是 React 中常用的 Hook 之一它返回一个可变的 ref 对象其 .current 属性被初始化为传入的参数initialValue。返回的 ref 对象在组件的整个生命周期内保持不变。
以下是一些使用 useRef 的场景和示例
1、存储React DOM 元素
我们首先回忆一下 vue 中的 ref ref 被用来给元素或子组件注册引用信息 —— vue 官网。引用信息将会注册在父组件的 $refs 对象上。
请看示例
!-- vm.$refs.p will be the DOM node --
p refphello/p!-- vm.$refs.child will be the child component instance --
child-component refchild/child-component如果在普通的 DOM 元素上使用引用指向的就是 DOM 元素如果用在子组件上引用就指向组件实例。
那么 react 中的 ref 是否也是这个作用我们可以从其用法上去做判断。
React 支持一个特殊的、可以附加到任何组件上的 ref 属性。此属性可以是一个由 React.createRef() 函数创建的对象、或者一个回调函数、或者一个字符串遗留 API —— 官网-ref 于是我们知道在 react 中 ref 属性可以是一个对象、回调函数亦或一个字符串。
1.1、useRef使用 存储React元素你可以使用 useRef 来存储一个React元素然后在需要的时候使用这个元素。这在一些情况下很有用比如你需要引用一个在组件的子元素列表中的特定元素。
简单示例
import { useRef, useEffect } from react;function MyComponent() {const inputRef useRef(null);useEffect(() {inputRef.current.focus(); //组件挂载时使其获得焦点}, []);return (divinput typetext ref{inputRef} //div);
}上面的代码使用 useRef 获取 input 元素的引用并在组件挂载时使其获得焦点。
1.2、对比类组件中的refs
1.2.1、String 类型的 Refs
下面这个例子将 ref 分别应用在 dom 元素和子组件中
class ASpan extends React.Component {render() {return spanclick/span}
}class EventDemo1 extends React.Component {handleClick() {console.log(this.refs)console.log(this.refs.aButton.innerHTML)}render() {return (// 箭头函数button refaButton onClick{() this.handleClick()}ASpan refaSpan //button);}
}点击按钮控制台输出
{aSpan: ASpan, aButton: button}
spanclick/spanTip用法上和 vue 中的 vm.$refs 非常相似。
注如果你目前还在使用 this.refs.textInput 这种方式访问 refs 我们建议用回调函数或 createRef API 的方式代替 —— 官网-过时 APIString 类型的 Refs
1.2.2、回调 Refs
React 也支持另一种设置 refs 的方式称为“回调 refs”。它能助你更精细地控制何时 refs 被设置和解除 —— 官网-回调 Refs
将字符串式 Refs 示例改成回调式。请看示例
class EventDemo1 extends React.Component {handleClick() {console.log(this.refs)console.log(this.button.innerHTML)}setButtonRef (element) {this.button element}render() {return (// 使用 ref 的回调函数将按钮 DOM 节点的引用存储到 React// 实例上比如 this.buttonbutton ref{this.setButtonRef} onClick{() this.handleClick()}click/button);}
}点击按钮控制台输出
{}
click回调函数中接受 React 组件实例或 HTML DOM 元素作为参数以使它们能在其他地方被存储和访问。
1.2.3、内联函数
可以将 refs 回调函数直接写在 ref 中。就像这样
// 与上面示例效果相同
button ref{element this.button element} onClick{() this.handleClick()}click
/button1.2.4、关于回调次数
如果 ref 回调函数是以内联函数的方式定义的在更新过程中它会被执行两次第一次传入参数 null然后第二次会传入参数 DOM 元素 —— 官网-关于回调 refs 的说明
请看示例
class EventDemo1 extends React.Component {state { date: new Date() }constructor() {super()setInterval(() {this.setState({ date: new Date() })}, 3000)}render() {return (button ref{element { this.button element; console.log(ref); }}click {this.state.date.toLocaleTimeString()}/button);}
}首先输出 ref然后每过 3 秒就会输出 2 次 ref。
Tip大多数情况下它是无关紧要的 —— 官网
1.2.5、createRef API
将回调 refs 的例子改成 createRef 形式。请看示例
class EventDemo1 extends React.Component {constructor() {super()this.button React.createRef()// this.textInput React.createRef()}handleClick() {// dom 元素或子组件可以在 ref 的 current 属性中被访问console.log(this.button.current.innerHTML)}render() {return (button ref{this.button} onClick{() this.handleClick()}click/button)}
}每点击一下 button控制台将输出一次 click。
Refs 是使用 React.createRef() 创建的并通过 ref 属性附加到 React 元素。在构造组件时通常将 Refs 分配给实例属性以便可以在整个组件中引用它们 —— 官网-创建 Refs
如果需要在增加一个 ref则需要再次调用 React.createRef()。
1.2.6、在函数组件中使用 ref
你不能在函数组件上使用 ref 属性因为他们没有实例 —— 官网-访问 Refs
而通过 useRef Hook 能让我们在函数组件使用 ref。重写 class 组件 EventDemo1
function EventDemo1() {const button React.useRef(null)function handleClick() {console.log(button.current.innerHTML)}return (button ref{button} onClick{() handleClick()}click/button)
}每点击一下 button控制台将输出一次 click。
const refContainer useRef(initialValue);useRef 返回一个可变的 ref 对象其 .current 属性被初始化为传入的参数initialValue —— 官网-useref 2、缓存值存在整个生命周期中 存储一个变量或者常量你可以使用 useRef 来存储一个变量或常量以便在组件的整个生命周期中使用。 useEffect里面的state的值是固定的这个是有办法解决的就是用useRef可以理解成useRef的一个作用就是相当于全局作用域一处被修改其他地方全更新。 本质上useRef 就像是可以在其 .current 属性中保存一个可变值的“盒子”。你应该熟悉 ref 这一种访问 DOM 的主要方式。如果你将 ref 对象以 div ref{myRef} / 形式传入组件则无论该节点如何改变React 都会将 ref 对象的 .current 属性设置为相应的 DOM 节点。然而useRef() 比 ref 属性更有用。它可以很方便地保存任何可变值其类似于在 class 中使用实例字段的方式。 请记住当 ref 对象内容发生变化时useRef 并不会通知你。变更 .current 属性不会引发组件重新渲染。如果想要在 React 绑定或解绑 DOM 节点的 ref 时运行某些代码则需要使用回调 ref 来实现。
import { useRef, useEffect } from react;function MyComponent() {const prevCountRef useRef(0);const [count, setCount] useState(0);useEffect(() {prevCountRef.current count;}, [count]);return (divpprev count: {prevCountRef.current}/ppcurrent count: {count}/pbutton onClick{() setCount(count 1)}Increment/button/div);
}在这个例子中我们使用 useState 来存储一个计数器的值同时也使用 useRef 来创建一个引用缓存了 count 的前一个值以便在组件的整个生命周期中访问这个值。当我们点击按钮count 更新时同时 prevCountRef.current 的值也会更新。注意虽然 prevCountRef.current 的值会随着 count 的变化而变化但 prevCountRef本身是一个可变的引用我们可以在任何地方通过prevCountRef.current 来获取当前的值用于记录前一次渲染的状态。
3、在 useEffect 中获取最新的值
import { useRef, useEffect } from react;function MyComponent(props) {const prevPropsRef useRef(null);useEffect(() {prevPropsRef.current props;});// ...return (// ...);
}上面的代码使用 useRef 缓存了 props 的前一个值可以用于比较前后两次 props 的变化情况。
使用 useRef 的原因是在函数组件中使用普通的变量无法保证变量值的实时性因为每次重新渲染组件时普通变量都会重新声明而 useRef 返回的是一个固定的引用不会因为重新渲染而改变。