Skip to content

Commit 7ee77db

Browse files
authored
Fix the rerender loop of profile hero data (#985)
* fix: fixed the hook to compare previous and current raw value * refactor: implement the new hook in other profile sections * fix: unnecessary useEffect * refactor: remove the comparison of previous/current value * fix: compare previous and current value
1 parent 010a98e commit 7ee77db

File tree

6 files changed

+50
-71
lines changed

6 files changed

+50
-71
lines changed

packages/web/components/Player/Section/PlayerColorDisposition.tsx

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { Link } from '@metafam/ds';
22
import { PlayerFragmentFragment } from 'graphql/autogen/types';
33
import { getPersonalityInfo } from 'graphql/queries/enums/getPersonalityInfo';
44
import { PersonalityOption } from 'graphql/types';
5+
import { useAnimateProfileChanges } from 'lib/hooks/players';
56
import React, { useEffect, useState } from 'react';
67
import { BOX_TYPE } from 'utils/boxTypes';
78

@@ -25,7 +26,6 @@ export const PlayerColorDisposition: React.FC<Props> = ({
2526
const [colorDisposition, setColorDisposition] = useState<
2627
0 | PersonalityOption | undefined
2728
>();
28-
const [animation, setAnimation] = useState<string>('fadeIn');
2929
const mask = player?.color_aspect?.mask;
3030
const type = mask && types?.[mask];
3131

@@ -37,13 +37,8 @@ export const PlayerColorDisposition: React.FC<Props> = ({
3737
loadTypes();
3838
}, []);
3939

40-
useEffect(() => {
41-
setAnimation('fadeOut');
42-
setTimeout(() => {
43-
setColorDisposition(type);
44-
setAnimation('fadeIn');
45-
}, 400);
46-
}, [mask, type]);
40+
const updateFN = () => setColorDisposition(type);
41+
const { animation } = useAnimateProfileChanges(type, updateFN);
4742

4843
return (
4944
<ProfileSection

packages/web/components/Player/Section/PlayerHero.tsx

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ import { EditProfileForm } from 'components/EditProfileForm';
2121
import { PlayerAvatar } from 'components/Player/PlayerAvatar';
2222
import { PlayerFragmentFragment } from 'graphql/autogen/types';
2323
import { useUser } from 'lib/hooks';
24-
import { useAnimation } from 'lib/hooks/players';
24+
import { useAnimateProfileChanges } from 'lib/hooks/players';
2525
import React, { useEffect, useState } from 'react';
2626
import { FaClock, FaGlobe } from 'react-icons/fa';
2727
import { getPlayerTimeZoneDisplay } from 'utils/dateHelpers';
@@ -207,7 +207,10 @@ export const PlayerHero: React.FC<Props> = ({ player, isOwnProfile }) => {
207207
const Availability: React.FC<AvailabilityProps> = ({ person }) => {
208208
const [availabilityHours, setAvailabilityHours] = useState<number>(0);
209209
const updateFN = () => setAvailabilityHours(person?.availability_hours || 0);
210-
const { animation } = useAnimation(person?.availability_hours, updateFN);
210+
const { animation } = useAnimateProfileChanges(
211+
person?.availability_hours,
212+
updateFN,
213+
);
211214
return (
212215
<Flex alignItems="center">
213216
<Box pr={2}>
@@ -235,7 +238,10 @@ const TimeZoneDisplay: React.FC<TimeZoneDisplayProps> = ({ person }) => {
235238
if (timeDisplay.offset) setOffset(timeDisplay.offset);
236239
};
237240

238-
const { animation } = useAnimation(timeDisplay.timeZone, updateFN);
241+
const { animation } = useAnimateProfileChanges(
242+
timeDisplay.timeZone,
243+
updateFN,
244+
);
239245
return (
240246
<Flex alignItems="center">
241247
<Box pr={1}>

packages/web/components/Player/Section/PlayerPronouns.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { MetaTag } from '@metafam/ds';
22
import { FlexContainer } from 'components/Container';
33
import { PlayerFragmentFragment } from 'graphql/autogen/types';
4-
import { useAnimation } from 'lib/hooks/players';
4+
import { useAnimateProfileChanges } from 'lib/hooks/players';
55
import React, { useState } from 'react';
66

77
import { PlayerHeroTile } from './PlayerHeroTile';
@@ -13,7 +13,7 @@ export const PlayerPronouns: React.FC<Props> = ({ person }) => {
1313
const updateFN = () => {
1414
setPronouns(person?.pronouns || '');
1515
};
16-
const { animation } = useAnimation(person?.pronouns, updateFN);
16+
const { animation } = useAnimateProfileChanges(person?.pronouns, updateFN);
1717

1818
return pronouns ? (
1919
<PlayerHeroTile title="Personal pronouns">

packages/web/components/Player/Section/PlayerSkills.tsx

Lines changed: 13 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@ import {
44
SkillCategory_Enum,
55
} from 'graphql/autogen/types';
66
import { SkillColors } from 'graphql/types';
7-
import React, { useEffect, useRef, useState } from 'react';
7+
import { useAnimateProfileChanges } from 'lib/hooks/players';
8+
import React, { useState } from 'react';
89
import { BOX_TYPE } from 'utils/boxTypes';
910

1011
import { ProfileSection } from '../../ProfileSection';
@@ -22,34 +23,20 @@ export const PlayerSkills: React.FC<Props> = ({
2223
const [playerSkills, setPlayerSkills] = useState<
2324
{ id: number; name: string; category: SkillCategory_Enum }[]
2425
>([]);
25-
const [animation, setAnimation] = useState<string>('fadeIn');
2626

27-
const usePrevious = <T extends unknown>(value: T): T | undefined => {
28-
const ref = useRef<T>();
29-
useEffect(() => {
30-
ref.current = value;
31-
});
32-
return ref.current;
27+
const updateFN = () => {
28+
if (player.skills) {
29+
setPlayerSkills(
30+
player.skills.map((s) => ({
31+
id: s.Skill.id,
32+
name: s.Skill.name,
33+
category: s.Skill.category,
34+
})),
35+
);
36+
}
3337
};
34-
const previousSkills = usePrevious(playerSkills);
3538

36-
useEffect(() => {
37-
if (JSON.stringify(playerSkills) !== JSON.stringify(previousSkills)) {
38-
setAnimation('fadeOut');
39-
setTimeout(() => {
40-
if (player.skills) {
41-
setPlayerSkills(
42-
player.skills.map((s) => ({
43-
id: s.Skill.id,
44-
name: s.Skill.name,
45-
category: s.Skill.category,
46-
})),
47-
);
48-
}
49-
setAnimation('fadeIn');
50-
}, 400);
51-
}
52-
}, [player, previousSkills, playerSkills]);
39+
const { animation } = useAnimateProfileChanges(player.skills, updateFN);
5340

5441
if (!player.skills?.length) {
5542
return null;

packages/web/components/Player/Section/PlayerType.tsx

Lines changed: 4 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { Text } from '@metafam/ds';
22
import { Player_Type, PlayerFragmentFragment } from 'graphql/autogen/types';
3-
import React, { useEffect, useRef, useState } from 'react';
3+
import { useAnimateProfileChanges } from 'lib/hooks/players';
4+
import React, { useState } from 'react';
45
import { BOX_TYPE } from 'utils/boxTypes';
56

67
import { FlexContainer } from '../../Container';
@@ -18,31 +19,9 @@ export const PlayerType: React.FC<Props> = ({
1819
onRemoveClick,
1920
}) => {
2021
const [playerType, setPlayerType] = useState<Player_Type | null>();
21-
const [animation, setAnimation] = useState<string>('fadeIn');
22+
const updateFN = () => setPlayerType(player.type);
2223

23-
const type = player?.type;
24-
25-
const usePrevious = <T extends unknown>(value: T): T | undefined => {
26-
const ref = useRef<T>();
27-
useEffect(() => {
28-
ref.current = value;
29-
});
30-
return ref.current;
31-
};
32-
const previousType = usePrevious(type);
33-
34-
// todo refactor so that usePrevious won't be needed anymore
35-
// something is retriggering useEffect when color disposition is changed, for example
36-
// i suspect the type object's reference is changing
37-
useEffect(() => {
38-
if (previousType?.title !== type?.title) {
39-
setAnimation('fadeOut');
40-
setTimeout(() => {
41-
setPlayerType(type);
42-
setAnimation('fadeIn');
43-
}, 400);
44-
}
45-
}, [type, previousType]);
24+
const { animation } = useAnimateProfileChanges(player.type, updateFN);
4625

4726
return (
4827
<ProfileSection

packages/web/lib/hooks/players.ts

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -297,19 +297,31 @@ const usePaginatedPlayers = (
297297
};
298298
};
299299

300-
export const useAnimation = (
300+
export const useAnimateProfileChanges = (
301301
depends: unknown,
302302
updateFN: () => void,
303303
): { [key: string]: string } => {
304304
const [animation, setAnimation] = useState('fadeIn');
305305

306+
const usePrevious = <T extends unknown>(value: T): T | undefined => {
307+
const ref = useRef<T>();
308+
useEffect(() => {
309+
ref.current = value;
310+
});
311+
return ref.current;
312+
};
313+
const previousValue = usePrevious(depends);
314+
306315
useEffect(() => {
307-
setAnimation('fadeOut');
308-
setTimeout(() => {
309-
updateFN();
310-
setAnimation('fadeIn');
311-
}, 400);
312-
}, [depends, updateFN]);
316+
if (JSON.stringify(previousValue) !== JSON.stringify(depends)) {
317+
setAnimation('fadeOut');
318+
setTimeout(() => {
319+
updateFN();
320+
setAnimation('fadeIn');
321+
}, 400);
322+
}
323+
// eslint-disable-next-line react-hooks/exhaustive-deps
324+
}, [depends]);
313325

314326
return { animation };
315327
};

0 commit comments

Comments
 (0)