今天在做项目的时候写了如下代码,目的是想对请求到的数据进行计算后用变量 dataSourceNum
渲染到下方标签体中。
let dataSourceNum = 0
useEffect(() => {
get("********").then(
(res) => {
const { data } = res;
data.map(item => {
dataSourceNum += item.dataSources*1
return dataSourceNum
})
},
(error) => {
console.log(error);
}
);
}, []);// eslint-disable-line
// 此处省略一万行
return (
<Card size="small" title='数据源数量'>
{dataSourceNum}
</Card>
)
但是这种写法在useEffect那块会产生一个警告:
Assignments to the ‘dataSourceNum’ variable from inside React Hook useEffect will be lost after each render. To preserve the value over time, store it in a useRef Hook and keep the mutable value in the ‘.current’ property. Otherwise, you can move this variable directly inside useEffect.
翻译过来意思是:
每次渲染后,从React Hook useEffect内部对“dataSourceNum”变量的赋值将丢失。要随时间保留该值,请将其存储在useRef Hook中,并将可变值保留在’.current’属性。
我们再来看React官方文档关于useRef Hook的介绍:
useRef 返回一个可变的 ref 对象,其 .current 属性被初始化为传入的参数(initialValue)。返回的 ref 对象在组件的整个生命周期内持续存在。
特点如下:
- 它可以很方便地保存任何可变值,其类似于在 class 中使用实例字段的方式。
- 它创建的是一个普通 Javascript 对象。而 useRef() 和自建一个 {current: …} 对象的唯一区别是,useRef 会在每次渲染时返回同一个 ref 对象。
- 当 ref 对象内容发生变化时,useRef 并不会通知你。变更 .current 属性不会引发组件重新渲染。如果想要在 React 绑定或解绑 DOM 节点的 ref 时运行某些代码,则需要使用回调 ref 来实现。
所以我们根据警告信息改用useRef来解决问题:
const dataSourceNum = useRef(0)
useEffect(() => {
get("********").then(
(res) => {
const { data } = res;
data.map(item => {
dataSourceNum.current += item.dataSources*1
return dataSourceNum
})
},
(error) => {
console.log(error);
}
);
}, []);// eslint-disable-line
return (
<Card size="small" title='数据源数量'>
{dataSourceNum.current}
</Card>
)
在其他场景中useRef还可以用来获取dom元素。