Hooks-useRef
作用:
- 访问 DOM 节点/react 元素
- useRef 替换 class 组件中的 createRef
- 使用 forwardRef 传递 ref 引用
- 使用 useImperativeHandle 自定义暴露实例值
- 保持变量引用
保持变量的引用
在下面这个例子中,如果我们只是想设置一个定时器,可以使用局部变量id
,但是如果我们想要在其他地方清除这个定时器,useRef
就够帮助我们保存定时器的引用。
1 | import React, { useState, useEffect, useRef } from 'react'; |
ref 回调函数实参不更新问题
1 | const CustomizeContext = createContext(defaultV); |
1 | import { |
有一个列表,为了保存列表项节点,我使用 ref 回调来处理。
有这么个场景,点击 layers 中的第一项并做删除操作,layers.splice(0, 1),然后更新 layers 引用
点击第二项时,我期望handleDropRefCallback
中的i
为 0,因为 layer 已经更新了,但是结果为 1,也就是还是首次 i 的值
纳闷了好久,后面才发现是key
属性key={layer.id}
保持了该节点的稳定,该节点没有重新渲染,所以 ref 的回调函数还是旧的回调函数,i 的值还是第一项还未删除时的值。
解决这个问题,只需要将 key 改为key={i}
,此时列表项重新渲染,handleDropRefCallback
中的i
就是期望值 0。
但是我们清楚,用下标作为 key 的值,如果列表发生更改(新增、删除)时,那么其他列表项的 key 值可能会发生变化,那么变化的部分就会造成没必要的重新渲染问题。所以我还是想用layer.id
作为 key 值,通过 id,遍历 layers,查找当前项所在的下标位置。
结果却出乎意外,发现 Provied.value 对象中updateLayersFn
函数中的 layers 还是旧值,难道 Provider 组件 value 对象中的函数引用了 layers,此时产生了闭包对象?