React结合Tailwind CSS实现每8条内容后插入广告横幅
实现方案
直接按下面的逻辑修改代码即可,核心是提前过滤有效广告、在文章渲染流程中按间隔插入通栏广告,同时修复原有代码的隐性bug:
- 首先修正原代码里广告位匹配的拼写错误:原代码写的
ad.add_space === "categoty"少了一个r,正确值是"category",这个bug会导致广告完全匹配不到 - 提前过滤出分类页可用的广告列表,加兜底逻辑,广告数量不足时不会抛错
- 渲染文章列表时,每渲染完8张卡片,就从广告列表顺序取一个广告插入,广告设置为跨4列通栏,不破坏原有4列网格布局
修改后的完整组件代码
import React from "react"; import Cards from "../../components/GridCards"; import Circle from "../../components/svgs/Circle"; // 静态生成页面路径 export async function getStaticPaths() { const res = await fetch("https://pranerbangla.com/api/vb1/category-tree"); const data = await res.json(); const content = data["data"]; const paths = content.map((pageName) => { return { params: { id: pageName.id.toString() }, }; }); return { paths, fallback: false, }; } // 拉取页面数据 export async function getStaticProps(context) { const id = context.params.id; const res = await fetch( "https://pranerbangla.com/api/vb1/category-to-post/" + id ); const data = await res.json(); // 原广告接口用http协议,https站点部署会触发混合内容拦截,统一改成https const resAdd = await fetch("https://pranerbangla.com/api/vb1/advertisement"); const adData = await resAdd.json(); const content = data["data"]; const contentAd = adData["data"]; return { props: { pages: content, advertise: contentAd, }, }; } function CategoryPage({ pages, advertise }) { // 提前过滤分类页可用广告,修正原拼写错误 const categoryAds = advertise.filter(ad => ad.add_space === "category"); let adIndex = 0; return ( <div> <div className="flex justify-between mx-48 border-b-2 my-8 "> {[pages[0]].map((pageItem, i) => { return ( <h1 key={i} className="flex items-center text-base text-3xl text-black mb-4 dark:text-white" > <Circle className=" h-3 pr-2 mb-1" /> {pageItem.category_name_bn} </h1> ); })} <h1 className="flex items-center text-base text-lg text-black mb-4 dark:text-white"> সাম্প্রতিক পোস্ট (206) </h1> </div> <div className="grid grid-cols-4 mb-4 gap-10 mx-48 "> {pages?.map((pageItem, index) => { return ( <React.Fragment key={pageItem.id}> <Cards title={pageItem.title_bn} category={pageItem.category_name_bn} time={pageItem.created_at} imgSrc={pageItem.image} route={pageItem.id} status={pageItem.status} /> {/* 索引从0开始,每渲染8个卡片后插入广告,同时判断剩余广告数量避免报错 */} {(index + 1) % 8 === 0 && adIndex < categoryAds.length && ( <div className="col-span-4"> <img className="h-32 w-full object-fill" src={`https://pranerbangla.com/${categoryAds[adIndex].image}`} alt="分类广告" /> </div> )} {/* 插入广告后广告索引自增 */} {(index + 1) % 8 === 0 && adIndex++} </React.Fragment> ); })} </div> </div> ); } export default CategoryPage;
改动说明
- 删除了原代码中把所有广告堆在页面顶部的渲染逻辑,广告不再集中堆叠
- 广告容器加了
col-span-4类,会自动占满网格4列宽度,不会挤在单格里破坏布局 - 给列表项加了唯一key,避免React渲染警告
- 所有接口统一用https协议,避免线上部署时的资源拦截问题
内容的提问来源于stack exchange,提问作者Romanch haque
相关产品推荐
相关产品推荐

