You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React父组件宽度传递给子组件时子组件始终获取0的问题

解决父组件传递动态宽度给子组件时子组件拿到0的问题

问题根源

你遇到的情况是组件渲染顺序导致的:

  1. 父组件初始渲染时,width默认值为0,此时会把0传给子组件
  2. 父组件的useEffect是在第一次渲染完成后才执行,这时才会获取到真实元素宽度并更新width状态
  3. 若子组件未正确响应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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 11:15:57