TL;DR: Want to use listRef.current.clientWidth for useEffect dependency.
I wanted to make a list where it automatically resizes its item's widths according to list's width. I'm so close but I can't detect the change of listRef.current.clientWidth
which is <div className="dynamic-list">
's width. At the first run listRef is null, so I can't have listRef.current.clientWidth
for the useEffect dependency. listRef ? listRef.current.clientWidth : null
for the dependency also doesn't work with use simple dependency warning
.
const DynamicList = ({
dataSource, renderItem, itemMaxWidth, itemHeight,
margin, height = 500, width = 700 }) => {
const windowWidth = useWindowDimensions().width;
const [itemStyle, setItemStyle] = useState({ width: itemMaxWidth, height: itemHeight });
const [currentWidth, setCurrentWidth] = useState(null);
const listRef = useRef();
useEffect(() => {
if (listRef) {
const num = Math.floor(listRef.current.clientWidth / itemMaxWidth)
console.log(
num,
listRef.current.clientWidth,
listRef.current
)
setItemStyle((pre) => ({
...pre,
height: itemHeight,
margin: margin,
width: (listRef.current.clientWidth / num) - (margin ? margin * 2 : 0),
}))
}
}, [listRef, windowWidth, itemMaxWidth, margin, itemHeight, width])
return (
<div
className="dynamic-list"
ref={listRef}
style={{
width: width,
height: height
}}
>
{
dataSource.map((item, index) => {
return (
<div style={itemStyle} key={index}>
{renderItem(item, index)}
</div>
)
})
}
</div>
);
};
export default DynamicList;
Using callback ref like @TopW3 said, I was able to solve the problem. Not fully satisfied though. Article that also helped me solve the problem
const DynamicList = ({
dataSource, renderItem, itemMaxWidth, itemHeight,
margin, height = 500, width = 700 }) => {
const windowWidth = useWindowDimensions().width; // 윈도우 크기 변화 감지용
const [itemStyle, setItemStyle] = useState({
width: itemMaxWidth,
height: itemHeight,
margin: margin
});
const [listWidth, setListWidth] = useState(null);
const onListRefSet = useCallback((ref) => {
if (ref)
if (ref.current)
setListWidth(ref.current.clientWidth);
})
useEffect(() => {
if (listWidth) {
const num = Math.floor(listWidth / itemMaxWidth);
setItemStyle((pre) => ({
...pre,
width: (listWidth / num) - (margin ? margin * 2 : 0),
}))
}
}, [listWidth, itemMaxWidth, margin, itemHeight, windowWidth])
return (
<div
className="dynamic-list"
ref={onListRefSet}
style={{
width: width,
height: height,
minWidth: itemMaxWidth
}}
>
{
dataSource.map((item, index) => {
return (
<div style={itemStyle} key={index}>
{renderItem(item, index)}
</div>
)
})
}
</div>
);
};
export default DynamicList;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With