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

React自定义条件组件HideIf报错:Cannot read properties of null (reading 'last_page')问题排查

React自定义条件渲染组件报错:Cannot read properties of null (reading 'last_page')

我想要在React中实现一个条件渲染组件,但遇到了问题。我原本的代码可以正常运行:

{(users.length === 0) ? (<></>) : ( <Pagination sx={{ mt: '1rem' }} page={page} count={pagination.last_page} onChange={handleChangePage} /> )}

但我希望改成如下自定义组件的形式:

const MyComponent = () => { 
  return ( 
    <HideIf condition={users.length === 0}> 
      <Pagination sx={{ mt: '1rem' }} page={page} count={pagination.last_page} onChange={handleChangePage} /> 
    </HideIf> 
  ); 
} 
const HideIf = ({condition, children}) => { 
  if(condition){ 
    return ( <></> ); 
  } else { 
    return ( <>{children}</> ); 
  } 
}

但这种写法触发了错误:Cannot read properties of null (reading 'last_page')。请问是不是即使condition为false,Pagination组件的属性仍会被读取?

你的猜测完全正确!问题出在React解析JSX的时机上:

当你写<HideIf><Pagination ... count={pagination.last_page} /></HideIf>时,React会先解析所有传递给HideIf的children——也就是先计算Pagination的所有props,包括pagination.last_page,然后才会把这个已经解析好的JSX元素传给HideIf组件。哪怕HideIf最终不会渲染这个子组件,props的计算过程已经提前完成了,所以当pagination是null或者undefined时,访问last_page就会抛出错误。

而你最初的三元表达式写法之所以没问题,是因为三元运算符是短路求值的:只有当条件users.length === 0为false时,才会去计算右侧的Pagination组件及其props,避免了不必要的属性访问。

解决方法

这里有几种可行的修复方案:

1. 使用Render Props模式

让HideIf接收一个返回JSX的函数作为子元素,这样只有当条件不满足时才会执行这个函数,从而延迟props的计算:

const MyComponent = () => { 
  return ( 
    <HideIf condition={users.length === 0}> 
      {() => <Pagination sx={{ mt: '1rem' }} page={page} count={pagination.last_page} onChange={handleChangePage} />}
    </HideIf> 
  ); 
} 

const HideIf = ({condition, children}) => { 
  if(condition){ 
    return <></>; 
  } else { 
    // 调用函数获取子组件
    return <>{children()}</>; 
  } 
}

2. 在HideIf内部封装条件判断逻辑

或者直接把条件判断和子组件的渲染逻辑结合,避免提前计算props:

// 调整HideIf的用法,直接传入渲染逻辑
const MyComponent = () => { 
  return ( 
    <HideIf condition={users.length === 0} render={() => (
      <Pagination sx={{ mt: '1rem' }} page={page} count={pagination.last_page} onChange={handleChangePage} />
    )} />
  ); 
} 

const HideIf = ({condition, render}) => { 
  return condition ? <></> : <>{render()}</>; 
}

3. 提前处理pagination的可选链

如果不想修改HideIf组件,也可以在传递props时使用可选链操作符,避免空值访问错误:

<Pagination sx={{ mt: '1rem' }} page={page} count={pagination?.last_page || 0} onChange={handleChangePage} />

这样即使pagination是null,pagination?.last_page会返回undefined,再通过|| 0给个默认值,就不会抛出错误了。

内容的提问来源于stack exchange,提问作者MarlexGC

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.27 12:22:30