react如何获取li每个的宽度
获取每个 <li> 元素宽度的方法
在 React 中获取每个 <li> 元素的宽度可以通过 ref 和 useEffect 结合实现。以下是具体实现步骤:
使用 useRef 和 useEffect
创建 ref 数组存储每个 <li> 的引用,并在组件挂载后通过 getBoundingClientRect() 获取宽度:
import React, { useRef, useEffect, useState } from 'react';
function ListComponent() {
const items = ['Item 1', 'Item 2', 'Item 3'];
const liRefs = useRef([]);
const [widths, setWidths] = useState([]);
useEffect(() => {
const newWidths = liRefs.current.map(ref => ref.getBoundingClientRect().width);
setWidths(newWidths);
}, []);
return (
<ul>
{items.map((item, index) => (
<li
key={index}
ref={el => liRefs.current[index] = el}
>
{item} - Width: {widths[index]?.toFixed(2)}px
</li>
))}
</ul>
);
}
动态响应宽度变化
若需监听窗口大小变化,添加 resize 事件监听器:
useEffect(() => {
const handleResize = () => {
const newWidths = liRefs.current.map(ref => ref.getBoundingClientRect().width);
setWidths(newWidths);
};
window.addEventListener('resize', handleResize);
handleResize(); // 初始计算
return () => window.removeEventListener('resize', handleResize);
}, []);
使用自定义 Hook 封装逻辑
将逻辑抽象为可复用的 Hook:
function useElementWidths(itemCount) {
const refs = useRef([]);
const [widths, setWidths] = useState([]);
useEffect(() => {
const updateWidths = () => {
setWidths(refs.current.map(ref => ref?.getBoundingClientRect().width || 0));
};
updateWidths();
window.addEventListener('resize', updateWidths);
return () => window.removeEventListener('resize', updateWidths);
}, [itemCount]);
return { refs, widths };
}
// 使用示例
function ListComponent() {
const items = ['Item 1', 'Item 2', 'Item 3'];
const { refs, widths } = useElementWidths(items.length);
return (
<ul>
{items.map((item, index) => (
<li key={index} ref={el => refs.current[index] = el}>
{item} - Width: {widths[index]?.toFixed(2)}px
</li>
))}
</ul>
);
}
注意事项
- 避免索引错位:确保
ref回调中的索引与渲染的列表项严格对应。 - 性能优化:频繁的
resize事件可能影响性能,可考虑使用防抖(debounce)技术。 - SSR 兼容:在服务端渲染时
getBoundingClientRect()不可用,需添加条件判断。
通过以上方法,可以准确获取并动态跟踪每个 <li> 元素的宽度。







