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

React Native Google Mobile Ads(RewardedAd)加载前白屏问题排查

问题分析与解决方案

代码存在的核心问题

  • 广告未加载完成(loaded为false)时,组件直接返回null,导致页面无任何可渲染内容,出现白屏。
  • 广告实例rewarded定义在组件外部,会被所有组件实例共享,易引发重复订阅、重复加载等异常。
  • 广告加载完成后立即自动调用rewarded.show(),强制在页面内容渲染前弹出广告,进一步加剧白屏感知。

白屏产生的直接原因

组件渲染逻辑中if (!loaded) return null是关键:在广告加载的2-3秒内,页面没有渲染任何DOM元素,系统只能显示空白屏幕,直到广告加载完成后才会渲染页面的文本和按钮内容。

修复后的示例代码

import React, { useState, useEffect } from "react";
import { View, Button, Text, ScrollView, ActivityIndicator } from 'react-native'
import { RewardedAd, RewardedAdEventType, TestIds } from 'react-native-google-mobile-ads';

const adUnitId = __DEV__ ? TestIds.REWARDED : 'ca-app-pub-3940256099942544/5224354917';

const Testing = ({ navigation }) => {
  const [loaded, setLoaded] = useState(false);
  const [isLoadingAd, setIsLoadingAd] = useState(true);
  // 将广告实例移到组件内部,避免跨实例共享
  const rewarded = RewardedAd.createForAdRequest(adUnitId, {
    requestNonPersonalizedAdsOnly: true,
    keywords: ['fashion', 'clothing'],
  });

  useEffect(() => {
    const unsubscribeLoaded = rewarded.addAdEventListener(RewardedAdEventType.LOADED, () => {
      setLoaded(true);
      setIsLoadingAd(false);
      // 改为用户主动触发广告,而非自动弹出
    });

    const unsubscribeFailed = rewarded.addAdEventListener(RewardedAdEventType.FAILED_TO_LOAD, () => {
      setIsLoadingAd(false);
    });

    const unsubscribeEarned = rewarded.addAdEventListener(
      RewardedAdEventType.EARNED_REWARD,
      reward => {
        console.log('User earned reward of ', reward);
      },
    );

    rewarded.load();

    return () => {
      unsubscribeLoaded();
      unsubscribeFailed();
      unsubscribeEarned();
    };
  }, []);

  return (
    <ScrollView>
      <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center', padding: 16 }}>
        <Text>
          Lorem Ipsum is simply dummy text of the printing and typesetting industry.
          Lorem Ipsum has been the industry's standard dummy text ever since the 1500s,
        </Text>
        {/* 广告加载状态显示 */}
        {isLoadingAd && <ActivityIndicator style={{ marginVertical: 16 }} size="large" />}
        {/* 广告加载完成后显示触发按钮 */}
        {loaded && (
          <Button 
            onPress={() => {
              rewarded.show();
              // 广告展示后重置状态,避免重复触发
              setLoaded(false);
            }} 
            title='观看广告获取奖励'
            style={{ marginVertical: 8 }}
          />
        )}
        <Button onPress={() => navigation.navigate('ThirdPage')} title='Next Screen'></Button>
      </View>
    </ScrollView>
  )
}

export default Testing

修复要点说明

  • 移除return null的逻辑,始终渲染页面核心内容,同时添加广告加载状态指示器(ActivityIndicator),避免白屏。
  • 将广告实例的创建移到组件内部,确保每个组件实例拥有独立的广告实例,避免状态冲突。
  • 把广告显示逻辑改为用户主动触发(按钮点击),既符合广告规范,也提升用户体验。
  • 添加广告加载失败监听,及时隐藏加载状态,避免无限等待。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 17:54:24