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

React Native中在View/Text内使用useEffect出现无报错白屏如何解决

问题根源

白屏是因为你完全违反了React Hooks的调用规则,触发了无限重渲染死循环,这类问题如果没开对应ESLint规则校验,开发环境经常不会抛明确报错,直接卡死页面。
React Hooks的核心要求是:所有Hook必须在组件顶层作用域、或者自定义Hook内部调用,绝对不能放在条件判断、循环、嵌套回调、JSX执行块里调用。React是靠每次渲染时Hook的调用顺序匹配对应状态的,一旦你把Hook放在条件、循环、JSX里,每次渲染的Hook调用顺序会变,直接导致内部状态匹配错乱,加上你在渲染执行阶段直接触发状态更新,就会进入「渲染→改状态→重渲染→再改状态」的死循环,最终页面白屏。

你代码里的具体错误点
  • 在if (pass >= letter.description?.length)条件分支内调用useEffect,属于条件调用Hook,破坏了Hook调用顺序一致性。
  • 在Text组件的JSX{}块内直接调用useEffect,属于渲染过程中执行Hook,而且useEffect没有任何可渲染的返回值,执行时会直接触发setPass更新,引爆无限重渲染。
  • 在FlatList的renderItem循环回调里调用useEffect,属于嵌套函数/循环内调用Hook,同样违反Hook调用规则。
  • 你维护pass变量做渲染计数的逻辑本身就不合理:FlatList渲染每一项时本身会暴露当前项的index,完全不需要额外用全局状态累加计数取数据,这种实现本身就会导致所有渲染项共用同一个pass值,渲染结果全部错乱。
修正方案

直接用renderItem回调自带的index取对应位置的数据即可,删掉多余的pass状态和错误放置的useEffect:

return (
  <View>
    <FlatList
      data={letter.description}
      numColumns={2}
      keyExtractor={(_, index) => index.toString()}
      renderItem={({ item, index }) => {
        // 直接用当前渲染项的索引取对应数据,不需要全局计数
        return (
          <View>
            <Text>
              {letter.data[index]}
              {"\n"}
            </Text>
            <Text>
              {item}
              {"\n"}
            </Text>
          </View>
        )
      }}
    />
  </View>
)

如果确实有监听pass值做重置的需求,把对应逻辑的useEffect放到组件最顶层,不要塞进渲染流程里:

// 组件顶层调用useEffect,符合Hook规则
useEffect(() => {
  if (pass >= letter.description?.length) {
    setPass(0)
  }
}, [pass, letter.description?.length])

建议项目里开启eslint-plugin-react-hooks的规则校验,所有违规调用Hook的写法会在编码阶段直接标红,能避免绝大多数Hook使用问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.01 04:36:26