Skip to content

Commit 31db2c5

Browse files
authored
refactor: simplify partner list components by introducing usePartnersList hook
1 parent 32b876d commit 31db2c5

File tree

3 files changed

+76
-77
lines changed

3 files changed

+76
-77
lines changed

apps/site/components/Common/Partners/PartnersIconList/index.tsx

Lines changed: 7 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,13 @@
11
'use client';
22

3-
import { useEffect, useRef, useState } from 'react';
43
import type { FC } from 'react';
54

5+
import usePartnersList from '#site/hooks/react-client/usePartnersList';
66
import { ICON_PARTNERS } from '#site/next.partners.constants';
7-
import type { PartnerCategory, Partners } from '#site/types';
7+
import type { PartnerCategory } from '#site/types';
88

99
import PartnerIcon from '../PartnerIcon';
1010
import style from './index.module.css';
11-
import { randomPartnerList } from '../utils';
1211

1312
type PartnersIconListProps = {
1413
maxLength?: number;
@@ -19,39 +18,11 @@ const PartnersIconList: FC<PartnersIconListProps> = ({
1918
maxLength = 6,
2019
categories,
2120
}) => {
22-
const initialRenderer = useRef(true);
23-
24-
const [seedList, setSeedList] = useState<Array<Partners>>(
25-
ICON_PARTNERS.slice(0, maxLength)
26-
);
27-
28-
useEffect(() => {
29-
// We intentionally render the initial default "mock" list of sponsors
30-
// to have the Skeletons loading, and then we render the actual list
31-
// after an enough amount of time has passed to give a proper sense of Animation
32-
// We do this client-side effect, to ensure that a random-amount of sponsors is renderered
33-
// on every page load. Since our page is natively static, we need to ensure that
34-
// on the client-side we have a random amount of sponsors rendered.
35-
// Although whilst we are deployed on Vercel or other environment that supports ISR
36-
// (Incremental Static Generation) whose would invalidate the cache every 5 minutes
37-
// We want to ensure that this feature is compatible on a full-static environment
38-
const renderSponsorsAnimation = setTimeout(() => {
39-
initialRenderer.current = false;
40-
41-
setSeedList(
42-
randomPartnerList(ICON_PARTNERS, {
43-
pick: maxLength,
44-
dateSeed: 5,
45-
category: categories,
46-
})
47-
);
48-
}, 0);
49-
50-
return () => clearTimeout(renderSponsorsAnimation);
51-
// We only want this to run once on initial render
52-
// We don't really care if the props change as realistically they shouldn't ever
53-
// eslint-disable-next-line react-hooks/exhaustive-deps
54-
}, []);
21+
const { seedList, initialRenderer } = usePartnersList({
22+
logos: ICON_PARTNERS,
23+
maxLength,
24+
categories,
25+
});
5526

5627
return (
5728
<div className={style.partnersIconList}>

apps/site/components/Common/Partners/PartnersLogoList/index.tsx

Lines changed: 7 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,13 @@
11
'use client';
22

3-
import { useEffect, useRef, useState } from 'react';
43
import type { FC } from 'react';
54

5+
import usePartnersList from '#site/hooks/react-client/usePartnersList';
66
import { LOGO_PARTNERS } from '#site/next.partners.constants';
7-
import type { PartnerCategory, Partners } from '#site/types';
7+
import type { PartnerCategory } from '#site/types';
88

99
import PartnerLogo from '../PartnerLogo';
1010
import style from './index.module.css';
11-
import { randomPartnerList } from '../utils';
1211

1312
type PartnersLogoListProps = {
1413
maxLength?: number;
@@ -21,46 +20,13 @@ const PartnersLogoList: FC<PartnersLogoListProps> = ({
2120
sort = 'weight',
2221
categories,
2322
}) => {
24-
const initialRenderer = useRef(true);
25-
26-
const [seedList, setSeedList] = useState<Array<Partners>>(() => {
27-
if (maxLength === null) {
28-
return LOGO_PARTNERS.filter(
29-
partner => !categories || partner.categories.includes(categories)
30-
);
31-
}
32-
return LOGO_PARTNERS.slice(0, maxLength);
23+
const { seedList, initialRenderer } = usePartnersList({
24+
logos: LOGO_PARTNERS,
25+
maxLength,
26+
sort,
27+
categories,
3328
});
3429

35-
useEffect(() => {
36-
// We intentionally render the initial default "mock" list of sponsors
37-
// to have the Skeletons loading, and then we render the actual list
38-
// after an enough amount of time has passed to give a proper sense of Animation
39-
// We do this client-side effect, to ensure that a random-amount of sponsors is renderered
40-
// on every page load. Since our page is natively static, we need to ensure that
41-
// on the client-side we have a random amount of sponsors rendered.
42-
// Although whilst we are deployed on Vercel or other environment that supports ISR
43-
// (Incremental Static Generation) whose would invalidate the cache every 5 minutes
44-
// We want to ensure that this feature is compatible on a full-static environment
45-
const renderSponsorsAnimation = setTimeout(() => {
46-
initialRenderer.current = false;
47-
48-
setSeedList(
49-
randomPartnerList(LOGO_PARTNERS, {
50-
pick: maxLength,
51-
dateSeed: 5,
52-
category: categories,
53-
sort,
54-
})
55-
);
56-
}, 0);
57-
58-
return () => clearTimeout(renderSponsorsAnimation);
59-
// We only want this to run once on initial render
60-
// We don't really care if the props change as realistically they shouldn't ever
61-
// eslint-disable-next-line react-hooks/exhaustive-deps
62-
}, []);
63-
6430
return (
6531
<div className={style.partnersLogoList}>
6632
{seedList.map((partner, index) => (
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
'use client';
2+
3+
import { useEffect, useRef, useState } from 'react';
4+
5+
import { randomPartnerList } from '#site/components/Common/Partners/utils';
6+
import type { PartnerCategory, Partners } from '#site/types/partners';
7+
8+
const usePartnersList = ({
9+
logos,
10+
maxLength,
11+
sort,
12+
categories,
13+
}: {
14+
logos: Array<Partners>;
15+
maxLength: number;
16+
sort?: 'name' | 'weight';
17+
categories?: PartnerCategory;
18+
}) => {
19+
const initialRenderer = useRef(true);
20+
21+
const [seedList, setSeedList] = useState<Array<Partners>>(() => {
22+
if (maxLength === null) {
23+
return logos.filter(
24+
partner => !categories || partner.categories.includes(categories)
25+
);
26+
}
27+
return logos.slice(0, maxLength);
28+
});
29+
30+
useEffect(() => {
31+
// We intentionally render the initial default "mock" list of sponsors
32+
// to have the Skeletons loading, and then we render the actual list
33+
// after an enough amount of time has passed to give a proper sense of Animation
34+
// We do this client-side effect, to ensure that a random-amount of sponsors is renderered
35+
// on every page load. Since our page is natively static, we need to ensure that
36+
// on the client-side we have a random amount of sponsors rendered.
37+
// Although whilst we are deployed on Vercel or other environment that supports ISR
38+
// (Incremental Static Generation) whose would invalidate the cache every 5 minutes
39+
// We want to ensure that this feature is compatible on a full-static environment
40+
const renderSponsorsAnimation = setTimeout(() => {
41+
initialRenderer.current = false;
42+
43+
setSeedList(
44+
randomPartnerList(logos, {
45+
pick: maxLength,
46+
dateSeed: 1,
47+
category: categories,
48+
sort,
49+
})
50+
);
51+
}, 0);
52+
53+
return () => clearTimeout(renderSponsorsAnimation);
54+
// We only want this to run once on initial render
55+
// We don't really care if the props change as realistically they shouldn't ever
56+
// eslint-disable-next-line react-hooks/exhaustive-deps
57+
}, []);
58+
59+
return { seedList, initialRenderer };
60+
};
61+
62+
export default usePartnersList;

0 commit comments

Comments
 (0)