如何在项目之间的 React Flatlist 中呈现 AdMob 横幅?

How to render AdMob banner in React Flatlist between items?

我有一个 React Native Flatlist,它仅在其数据更改时才重新呈现。

我给它以下数据(作为 prop):

const posts = [
    {
       ...post1Data
    },
    {
       ...post2Data
    },
    {
       ...post3Data
    },
    {
       ...post4Data
    },
    {
       ...post5Data
    },
]

这是我的 FlatList renderItem:

const renderItem = useCallback(({ item, index }) => {
  const { id, userData, images, dimensions, text } = item;

  return (
    <View
      onLayout={(event) => {
        itemHeights.current[index] = event.nativeEvent.layout.height;
      }}
    >
      <Card
        id={id}
        cached={false}
        userData={userData}
        images={images}
        dimensions={dimensions}
        text={text}
      />
    </View>
  );
}, []);

如何在不跳过 posts 数组中的任何数据的情况下以 5% 的概率在 FlatList 数据之间添加 AdMob 广告?

我试过这个:

const renderItem = useCallback(({ item, index }) => {
  const { id, userData, images, dimensions, text } = item;

  if (Math.random() < 0.05) return <Ad ... />

  return (
    <View
      onLayout={(event) => {
        itemHeights.current[index] = event.nativeEvent.layout.height;
      }}
    >
      <Card
        id={id}
        cached={false}
        userData={userData}
        images={images}
        dimensions={dimensions}
        text={text}
      />
    </View>
  );
}, []);

但这会导致 2 个问题:

  1. 数据中的某些项目被跳过(未返回)
  2. 当 flatlist 重新渲染时(因为它的一些 props 发生变化)广告可能会消失(有 95% 的几率)。

有什么想法吗?我应该像这样在 Card 组件的页脚中随机呈现广告吗?

const Card = memo ((props) => {
    ...
    return (
       <AuthorRow ... />

       <Content ... />

       <SocialRow ... /> {/* Interaction buttons */}

       <AdRow />
    )
}, (prevProps, nextProps) => { ... });



const AdRow = memo(() => {
   return <Ad ... />
}, () => true);

我不太确定这个选项,它有效,但它可能违反 admob 规定 (?)(因为我正在调整广告以适应我的卡片组件的布局)

我将不胜感激 guidance/help。谢谢。

我不确定您是否找到了解决此问题的方法,但我通过将“虚拟”项目注入数据集中,然后使用根据类型切换的组件包装 renderItem 组件来实现此目的每一项。

假设你的 flatlist 是这样声明的:

<FlatList data={getData()} renderItem={renderItem}/>

并且您的数据集被加载到一个名为 sourceData 的变量中,该变量与状态相关联。让我们假设您的 sourceData 数组中的一个条目如下所示。请注意 'type' 字段作为类型鉴别器:

{
  "id": "d96dce3a-6034-47b8-aa45-52b8d2fdc32f",
  "name": "Joe Smith",
  "type": "person"
}

然后你可以像这样声明一个函数:

const getData = React.useCallback(() => {
  let outData = [];
  outData.push(...sourceData);
  
  // Inject ads into array
  for (let i = 4; i < outData.length; i += 5)
  {
    outData.splice(i, 0, {type:"ad"});
  }
  return outData;
}, [sourceData]);

... 这将从第 5 个项目开始,每第 4 个项目之间将广告注入数据数组。 (由于我们将新数据推入数组,i += 5 意味着每第 4 个项目之间将放置一个广告。而 let i = 4 意味着我们的第一个广告将在列表中的第 5 个项目之后展示)

最后,渲染时在项目类型之间切换:

const renderItem = ({ item }) => (
  item.type === 'ad'
  ?
  <AdComponent ...props/>
  :
  <DataComponent ...props/>
);