reactjs - 我希望这个 useRef 和 useEffect 组合会失败……为什么会成功?
问题描述
我希望这useEffect
在第一次渲染时会失败,因为我会假设innerCarouselRef.current
在第一次渲染时未定义并且它会调用getBoundingClientRect
. 为什么它起作用/为什么innerCarouselRef.current
在运行时定义useEffect
?
import React from 'react';
import { debounce } from 'lodash';
export default function Carousel({ RenderComponent }) {
const [innerCarouselWidth, setInnerCarouselWidth] = React.useState(0);
const [itemWidth, setItemWidth] = React.useState(0);
const innerCarouselRef = useRef();
const itemRef = useRef();
const content = data.map((el, i) => {
return (
<div key={`item-${i}`} ref={i === 0 ? itemRef : undefined}>
<RenderComponent {...el} />
</div>
);
});
useEffect(() => {
const getElementWidths = () => {
setInnerCarouselWidth(innerCarouselRef.current.getBoundingClientRect().width); // why doesn't this call to getBoundingClientRect() break?
setItemWidth(itemRef.current.getBoundingClientRect().width);
};
getElementWidths();
const debouncedListener = debounce(getElementWidths, 500);
window.addEventListener('resize', debouncedListener);
return () => window.removeEventListener('resize', debouncedListener);
}, []);
return (
<div className="inner-carousel" ref={innerCarouselRef}>
{content}
</div>
)
}
解决方案
React 在更新 DOM 后运行效果(我们通常希望它以这种方式工作)。在您的情况下,效果在组件安装后运行,因此innerCarouselRef.current
已设置。
我建议阅读useEffect
文档以获得更好的理解。
推荐阅读
- mongodb - 尝试从命名空间“MongoDB\Driver\Monitoring”加载接口“CommandSubscriber”
- c# - 如何在 C# 中将每个新连接的对象添加到每个对象的列表中?
- r - 如何使用 R 代码从 4 个文件夹中创建一个大型 .csv 文件,每个文件夹包含 100 个文件?
- linq - EF Core 3.1 中的 Group By 和 To 字典
- javascript - javascript: 命名的 Firebase 应用程序已存在 (app/duplicate-app)
- node.js - 使用 Node 和 Axios 处理网络超时
- c++ - 如何使用 C++ 编译器在 VS 代码中使用 IntelliSense 的包含路径
- php - Ajax 不会在数据库中输入数据
- javascript - 在 CesiumJS 不规则矩形(多边形)中拟合图像材料
- sql - 当 1 个表看起来重复但不是时,使用连接进行 SQL 更新