React父组件宽度传递给子组件时子组件始终获取0的问题
解决父组件传递动态宽度给子组件时子组件拿到0的问题
问题根源
你遇到的情况是组件渲染顺序导致的:
- 父组件初始渲染时,
width默认值为0,此时会把0传给子组件 - 父组件的
useEffect是在第一次渲染完成后才执行,这时才会获取到真实元素宽度并更新width状态 - 若子组件未正确响应props更新,或是你只关注了初始渲染的值,就会误以为一直拿到0
具体解决方案
1. 完善父组件的宽度获取逻辑
确保父组件能正确获取元素宽度,且窗口大小变化时实时更新:
const projectVisor = useRef() const [width, setWidth] = useState(0) useEffect(() => { // 封装更新宽度的函数 const updateWidth = () => { if (projectVisor.current) { setWidth(projectVisor.current.offsetWidth) } } // 组件挂载后立即执行,获取初始宽度 updateWidth() // 监听窗口resize事件,实时更新宽度 window.addEventListener('resize', updateWidth) // 组件卸载时移除监听,避免内存泄漏 return () => window.removeEventListener('resize', updateWidth) }, [])
2. 确保子组件响应props更新
- 若子组件是函数组件:直接使用
props.width即可,父组件更新width状态后会重新渲染,子组件会自动拿到最新值 - 若子组件是类组件:在
componentDidUpdate中处理props变化
componentDidUpdate(prevProps) { if (prevProps.width !== this.props.width) { // 在这里处理宽度变化后的业务逻辑 } }
3. 可选:避免子组件接收初始0值
如果不想让子组件在初始阶段拿到0,可在父组件中做条件渲染,仅当宽度有效时渲染子组件:
{width > 0 && <ProjectItem width={width} />}
额外优化:用useLayoutEffect提前获取宽度
若想尽可能早拿到宽度,可把useEffect换成useLayoutEffect——它会在DOM更新完成后、浏览器绘制前执行,比useEffect时机更早,能减少子组件拿到0值的时间:
useLayoutEffect(() => { const updateWidth = () => { if (projectVisor.current) { setWidth(projectVisor.current.offsetWidth) } } updateWidth() window.addEventListener('resize', updateWidth) return () => window.removeEventListener('resize', updateWidth) }, [])
内容的提问来源于stack exchange,提问作者Igor Meshalkin
相关产品推荐
相关产品推荐

