公司做网站需要注意些什么问题,怎么做招投标网站,网站如何做站内站,东莞微信网站建设咨询目录 1#xff0c;介绍2#xff0c;和 React.createRef() 的区别3#xff0c;计时器的问题 目前来说#xff0c;因为函数组件每次触发更新时#xff0c;都会重新运行。无法像类组件一样让一些内容保持不变。 所以才出现了各种 HOOK 函数#xff1a;useState#xff0c;u… 目录 1介绍2和 React.createRef() 的区别3计时器的问题 目前来说因为函数组件每次触发更新时都会重新运行。无法像类组件一样让一些内容保持不变。 所以才出现了各种 HOOK 函数useStateuseCallbackuseMemo 等来辅助实现和类组件相似的功能。 useRef 也是这样的目的。
1介绍
在之前的文章中介绍了 ref用于获取组件或真实DOM元素的引用。
而 useRef 作用相同不过可以在函数组件中使用。同时它会返回对象的固定引用。 换句话说当函数组件重新运行时useRef() 前后2次返回的对象引用地址相同。 一个节点React元素对应一个唯一的对象。 React.createRef() 使用举例
import React, { useState } from react;export default function App() {const refInput React.createRef();return (input ref{refInput}/inputbuttononClick{() {console.log(refInput.current.value);}}获取 inputRef/button/);
}换成 useRef仅需要替换一行代码
const refInput React.createRef();
// 替换为
const refInput useRef();2和 React.createRef() 的区别
上面的代码中看起来只是一行代码的区别但本质上处理逻辑不同。
React.createRef()如果 ref 的值发生变动函数组件重新渲染则将旧值设为 nulluseRef()函数组件重新渲染多次时所有返回的对象的引用地址相同。
验证下 简单修改下将每次更新后的新 ref 放到 window 对象中对比下
import React, { useRef, useState } from react;window.arr [];
export default function App() {const refInput React.createRef();window.arr.push(refInput);const [n, setN] useState(); // 只是为了重新渲染组件。return (inputref{refInput}typetextvalue{n}onChange{(e) {setN(e.target.value);}}//);
}多次改变 input.value 时检查 window.arr 替换为 const refInput useRef(); 3计时器的问题
在之前介绍 useEffect 时提到了下面的写法是有问题的。
因为 useEffect 只会执行一次所以在计时器中通过闭包获取的状态变量 n 永远都是10
export default function App() {const [n, setN] useState(10);useEffect(() {const timer setInterval(() {setN(n - 1);}, 1000);return () {clearInterval(timer);};}, []);return div{n}/div;
}该问题通过将依赖项 n 传入即可。但会引起另一个问题 每次函数重新运行都会再次执行 useEffect开启计时器又销毁计时器开销很大。
export default function App() {const [n, setN] useState(10);useEffect(() {const timer setInterval(() {setN(n - 1);}, 1000);return () {clearInterval(timer);};}, [n]);return div{n}/div;
}所以可通过 useRef 来将函数重新运行后的新值传递给计时器同时 useEffect 也只会运行一次开启一次计时器 注意useRef() 返回的虽然是同一个对象但 setN 修改的是它的 current 属性。所以计时器每次获取的都是新值。 export default function App() {const [n, setN] useState(10);const refN useRef(n);useEffect(() {const timer setInterval(() {setN(--refN.current);}, 1000);return () {clearInterval(timer);};}, []);return div{n}/div;
}以上。