Skip to content

Commit 51e949d

Browse files
remove DOM element on unmount
1 parent a5c760b commit 51e949d

File tree

1 file changed

+46
-34
lines changed

1 file changed

+46
-34
lines changed

dotcom-rendering/src/components/LiveBlogEpic.importable.tsx

Lines changed: 46 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -245,10 +245,54 @@ export const LiveBlogEpic = ({
245245

246246
const [pageUrl, setPageUrl] = useState<string | undefined>();
247247

248+
const [epicPlaceholder, setEpicPlaceholder] = useState<HTMLElement | null>(
249+
null,
250+
);
251+
248252
useEffect(() => {
249253
setPageUrl(window.location.origin + window.location.pathname);
250254
}, []);
251255

256+
useEffect(() => {
257+
/**
258+
* Here we decide where to insert the epic.
259+
*
260+
* If the url contains a permalink then we
261+
* want to insert it immediately after that block to prevent any CLS issues.
262+
*
263+
* Otherwise, we choose a random position near the top of the blog
264+
*/
265+
const placeholder = document.createElement('article');
266+
if (window.location.href.includes('#block-')) {
267+
// Because we're using a permalink there's a possibility the epic will render in
268+
// view. To prevent confusing layout shift we initially hide the message so that
269+
// we can reveal (animate in) it once it has been rendered
270+
placeholder.classList.add('pending');
271+
const blockId = window.location.hash.slice(1);
272+
const blockLinkedTo = document.getElementById(blockId);
273+
if (blockLinkedTo) {
274+
insertAfter(blockLinkedTo, placeholder);
275+
}
276+
placeholder.classList.add('reveal');
277+
placeholder.classList.remove('pending');
278+
} else {
279+
// This is a simple page load so we simply insert the epic somewhere near the top
280+
// of the blog
281+
const randomPosition = Math.floor(Math.random() * 3) + 1; // 1, 2 or 3
282+
const aBlockNearTheTop =
283+
document.querySelectorAll<HTMLElement>('article.block')[
284+
randomPosition
285+
];
286+
if (aBlockNearTheTop) {
287+
insertAfter(aBlockNearTheTop, placeholder);
288+
}
289+
}
290+
setEpicPlaceholder(placeholder);
291+
return () => {
292+
placeholder.remove();
293+
};
294+
}, []);
295+
252296
// First construct the payload
253297
const payload = usePayload({
254298
shouldHideReaderRevenue,
@@ -258,40 +302,8 @@ export const LiveBlogEpic = ({
258302
pageId,
259303
keywordIds,
260304
});
261-
if (!ophanPageViewId || !payload || !pageUrl) return null;
262-
263-
/**
264-
* Here we decide where to insert the epic.
265-
*
266-
* If the url contains a permalink then we
267-
* want to insert it immediately after that block to prevent any CLS issues.
268-
*
269-
* Otherwise, we choose a random position near the top of the blog
270-
*/
271-
const epicPlaceholder = document.createElement('article');
272-
if (window.location.href.includes('#block-')) {
273-
// Because we're using a permalink there's a possibility the epic will render in
274-
// view. To prevent confusing layout shift we initially hide the message so that
275-
// we can reveal (animate in) it once it has been rendered
276-
epicPlaceholder.classList.add('pending');
277-
const blockId = window.location.hash.slice(1);
278-
const blockLinkedTo = document.getElementById(blockId);
279-
if (blockLinkedTo) {
280-
insertAfter(blockLinkedTo, epicPlaceholder);
281-
}
282-
epicPlaceholder.classList.add('reveal');
283-
epicPlaceholder.classList.remove('pending');
284-
} else {
285-
// This is a simple page load so we simply insert the epic somewhere near the top
286-
// of the blog
287-
const randomPosition = Math.floor(Math.random() * 3) + 1; // 1, 2 or 3
288-
const aBlockNearTheTop =
289-
document.querySelectorAll<HTMLElement>('article.block')[
290-
randomPosition
291-
];
292-
if (aBlockNearTheTop) {
293-
insertAfter(aBlockNearTheTop, epicPlaceholder);
294-
}
305+
if (!ophanPageViewId || !payload || !pageUrl || !epicPlaceholder) {
306+
return null;
295307
}
296308

297309
return createPortal(

0 commit comments

Comments
 (0)