fix: stabilize AdFrame with useMemo to prevent infinite re-render loop

- Wrap enabledNetworks in useMemo to avoid new array reference every render
- Use string key for useEffect dependency instead of array reference
- Remove slides from loadAd dependency array
- Remove stale GitHub Pages workflow (Vercel handles deploys)
- Add dev-server.log to .gitignore
This commit is contained in:
MR CYBER
2026-07-18 06:56:34 -07:00
parent 9fb5acce47
commit 63f2cab786
3 changed files with 18 additions and 59 deletions
-46
View File
@@ -1,46 +0,0 @@
name: Deploy to GitHub Pages
on:
push:
branches: ["master"]
workflow_dispatch:
permissions:
contents: read
pages: write
id-token: write
concurrency:
group: "pages"
cancel-in-progress: false
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Node
uses: actions/setup-node@v4
with:
node-version: "20"
cache: npm
- name: Install dependencies
run: npm ci
- name: Build
run: npm run build
- name: Upload artifact
uses: actions/upload-pages-artifact@v3
with:
path: ./out
deploy:
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
runs-on: ubuntu-latest
needs: build
steps:
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v4
+1
View File
@@ -21,6 +21,7 @@ dist/
npm-debug.log*
yarn-debug.log*
yarn-error.log*
dev-server.log
# typescript
*.tsbuildinfo
+17 -13
View File
@@ -1,6 +1,6 @@
"use client";
import { useState, useEffect, useRef, useCallback } from "react";
import { useState, useEffect, useRef, useCallback, useMemo } from "react";
import { useMonetizationConfig } from "@/hooks/useRuntimeConfig";
interface AdFrameProps {
@@ -33,20 +33,26 @@ export default function AdFrame({
const placement = adPlacements.find((p) => p.slot === slot);
const enabledNetworks = (placement?.networks
? adNetworks
.filter((n) => n.enabled && placement.networks?.includes(n.id))
.sort((a, b) => a.priority - b.priority)
: adNetworks
.filter((n) => n.enabled)
.sort((a, b) => a.priority - b.priority)
const enabledNetworks = useMemo(
() =>
(placement?.networks
? adNetworks
.filter((n) => n.enabled && placement.networks?.includes(n.id))
.sort((a, b) => a.priority - b.priority)
: adNetworks
.filter((n) => n.enabled)
.sort((a, b) => a.priority - b.priority)
),
[adNetworks, placement]
);
const enabledNetworkKey = enabledNetworks.map((n) => n.id).join(",");
useEffect(() => {
if (enabledNetworks.length === 0) return;
setSlides(enabledNetworks.map((n) => ({ networkId: n.id, loaded: false, failed: false })));
setActiveIndex(0);
}, [enabledNetworks]);
}, [enabledNetworkKey]);
const markLoaded = useCallback((networkId: string) => {
setSlides((prev) =>
@@ -99,9 +105,7 @@ export default function AdFrame({
setTimeout(() => {
observer.disconnect();
if (!slides[networkIndex]?.loaded) {
markFailed(network.id);
}
markFailed(network.id);
}, 5000);
};
@@ -153,7 +157,7 @@ export default function AdFrame({
markFailed(network.id);
}
},
[enabledNetworks, format, slot, markLoaded, markFailed, slides]
[enabledNetworks, format, slot, markLoaded, markFailed]
);
useEffect(() => {