引用 DOM 元素的 React Hook 在第一次调用时返回"null"



我有一个钩子getBoundingClientRect它捕获了 ref DOM 元素的对象。问题是,在第一次渲染时,它返回null并且我只需要在组件上的第一次渲染时获取值。

我在功能组件中像这样使用它:

const App = () => {
// create ref 
const rootRef = useRef(null);
// get Client Rect of rootRef 
const refRect = useBoundingClientRect(rootRef);
useEffect(()=> {
// return "null" the first time
// return "DOMRect" when refRect is update
console.log(refRect)
}, [refRect])
return <div ref={rootRef} >App</div>
}

这里是 useBoundingClientRect 钩子,我在 App Component 中调用。

export function useBoundingClientRect(pRef) {
const getBoundingClientRect = useCallback(() => {
return pRef && pRef.current && pRef.current.getBoundingClientRect();
}, [pRef]);
const [rect, setRect] = useState(null);
useEffect(() => {
setRect(getBoundingClientRect());
},[]);
return rect;
}

问题是我想在 init 上缓存 boundingClientRect 对象,而不是第二次重新渲染组件:

// App Component
useEffect(()=> {
// I would like to get boundingClientRect the 1st time useEffect is call.
console.log(refRect)
// empty array allow to not re-execute the code in this useEffect
}, [])

我查看了一些教程和文档,发现有些人使用useRef而不是useState钩子来保持价值。所以我尝试在我的useboundingClientRect钩子中使用它来捕获并返回 boundingClientRect 值在我的应用程序组件的第一个渲染时。它有效...部分地:

export function useBoundingClientRect(pRef) {
const getBoundingClientRect = useCallback(() => {
return pRef && pRef.current && pRef.current.getBoundingClientRect();
}, [pRef]);
const [rect, setRect] = useState(null);
// create a new ref
const rectRef = useRef(null)
useEffect(() => {
setRect(getBoundingClientRect());
// set value in ref
const rectRef = getBoundingClientRect()
},[]);
//  return rectRef for the first time 
return rect === null ? rectRef : rect;
}

现在,应用程序组件中的console.log(rectRef)允许在第一次渲染时访问该值:

// App Component
useEffect(()=> {
console.log(refRect.current)
}, [])

但是如果我尝试从钩子返回refRect.currentuseBoundingClientRect返回null.(什么?!

如果有人能向我解释这些错误。提前感谢!

您需要在此处了解引用、突变和更新的异步性质。

首先,当您使用 state 来存储clientRect属性时,当您的自定义挂钩运行时useEffect,它会在 state 中设置值,该值将反映在下一个渲染周期中,因为状态更新是异步的。这就是为什么在第一次渲染时您会看到undefined.

其次,当你返回rectRef时,你实际上是在返回一个对象,当useBoundingClientRect中的useEffect运行时,你稍后会在其中发生变异。数据在useEffect运行之前返回,因为它在呈现周期之后运行。现在,当组件中的useEffect运行时,即在自定义挂钩中的useEffect运行之后,数据已经存在,并且已通过前一个useEffect在其引用处进行了更新,因此您会看到正确的数据。

最后,如果您返回现在不可变值的rectRef.current,则自定义钩子会更新该值,但自上一个引用null以来,会在新的引用处更新该值,因此您看不到组件useEffect方法的变化。

相关内容

  • 没有找到相关文章

最新更新