yandexmobile / yandex-ads-react-native-plugin

Apache License 2.0
3 stars 0 forks source link

adSize error #3

Open YoungYanchi opened 2 weeks ago

YoungYanchi commented 2 weeks ago

При вызове

 let adSize = await BannerAdSize.inlineSize(Dimensions.get('window').width, 250);

ERROR Error: Objects are not valid as a React child (found: object with keys {_h, _i, _j, _k}). If you meant to render a collection of children, use an array instead.

если убрать async await

Error: You attempted to set the key _i with the value 3 on an object that is meant to be immutable and has been frozen.

const renderBanner = () => {
        let adSize = BannerAdSize.inlineSize(Dimensions.get('window').width, 250);

        return (
            <Animated.View style={[styles.bannerContainer, animatedStyle]}>

                    {
                        adSize && (
                            <BannerView
                                size={adSize}
                                adUnitId={getAdUnitId(variant)}
                                adRequest={adRequest}
                                onAdLoaded={() => console.log('Did load')}
                                onAdFailedToLoad={(event) => console.log(`Did fail to load with error: ${JSON.stringify(event.nativeEvent)}`)}
                                onAdClicked={() => console.log('Did click')}
                                onLeftApplication={() => console.log('Did leave application')}
                                onReturnToApplication={() => console.log('Did return to application')}
                                onAdImpression={(event) => console.log(`Did track impression: ${JSON.stringify(event.nativeEvent.impressionData)}`)}
                                onAdClose={() => console.log('Did close')}
                            />
                        )
                    }

            </Animated.View>
        );
    };

Подскажите пожалуйста, куда копать и в чем могут быть потенциальный проблемы?

SergeyA commented 2 weeks ago

Мне кажется проблема в том, что вы используете асинхронный вызов в не асинхронной функции renderBanner. Я у себя объединил асинхронную и синхронную логику таким образом:

export const MyBanner = (keywords: string) => {

  const [adSize, setAdSize] = useState(null as BannerAdSize | null);

  const adRequest = useMemo(() => new AdRequest({
    contextQuery: keywords,
  }), [keywords]);

  // Оборачиваем асинхронный вызов в useEffect. 
  // После вычисления размера сохраняем его в стейте adSize, что вызовет перерисовку банера с заданным размером
  useEffect(() => {
    BannerAdSize.stickySize(Dimensions.get('window').width)
      .then(size => { 
        setAdSize(size);
      })

  }, [Dimensions.get('window').width]);

  // Не рендерим банер до тех пор, пока не будет вычислен требуемый размер
  if(!adSize)
    return null;

  return adSize && <BannerView
    adUnitId={"demo-banner-yandex"}
    size={adSize}
    adRequest={adRequest}
    ...
  />

}
mobile-ads-github commented 1 week ago

@YoungYanchi Здравствуйте! Благодарим за обращение. Да, @SergeyA прав, проблема в вашем коде в том, что вы используете асинхронное BannerAdSize API, в синхронной функции renderBanner().

Корректно в данном случае будет запрашивать рассчет размера в хуке useEffect, сохранять этот размер в state, а в самом компоненте отображать баннер, только если размер рассчитан.

Рекомендуем обратить внимание на пример интеграции: https://github.com/yandexmobile/yandex-ads-react-native-plugin/blob/main/src/screens/ads/inlineBanner.tsx