mirror of
https://github.com/MetaFam/TheGame.git
synced 2026-04-24 03:00:09 -04:00
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
This commit is contained in:
@@ -2,6 +2,7 @@ import { Link } from '@metafam/ds';
|
||||
import { PlayerFragmentFragment } from 'graphql/autogen/types';
|
||||
import { getPersonalityInfo } from 'graphql/queries/enums/getPersonalityInfo';
|
||||
import { PersonalityOption } from 'graphql/types';
|
||||
import { useAnimateProfileChanges } from 'lib/hooks/players';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { BOX_TYPE } from 'utils/boxTypes';
|
||||
|
||||
@@ -25,7 +26,6 @@ export const PlayerColorDisposition: React.FC<Props> = ({
|
||||
const [colorDisposition, setColorDisposition] = useState<
|
||||
0 | PersonalityOption | undefined
|
||||
>();
|
||||
const [animation, setAnimation] = useState<string>('fadeIn');
|
||||
const mask = player?.color_aspect?.mask;
|
||||
const type = mask && types?.[mask];
|
||||
|
||||
@@ -37,13 +37,8 @@ export const PlayerColorDisposition: React.FC<Props> = ({
|
||||
loadTypes();
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
setAnimation('fadeOut');
|
||||
setTimeout(() => {
|
||||
setColorDisposition(type);
|
||||
setAnimation('fadeIn');
|
||||
}, 400);
|
||||
}, [mask, type]);
|
||||
const updateFN = () => setColorDisposition(type);
|
||||
const { animation } = useAnimateProfileChanges(type, updateFN);
|
||||
|
||||
return (
|
||||
<ProfileSection
|
||||
|
||||
@@ -21,7 +21,7 @@ import { EditProfileForm } from 'components/EditProfileForm';
|
||||
import { PlayerAvatar } from 'components/Player/PlayerAvatar';
|
||||
import { PlayerFragmentFragment } from 'graphql/autogen/types';
|
||||
import { useUser } from 'lib/hooks';
|
||||
import { useAnimation } from 'lib/hooks/players';
|
||||
import { useAnimateProfileChanges } from 'lib/hooks/players';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { FaClock, FaGlobe } from 'react-icons/fa';
|
||||
import { getPlayerTimeZoneDisplay } from 'utils/dateHelpers';
|
||||
@@ -207,7 +207,10 @@ export const PlayerHero: React.FC<Props> = ({ player, isOwnProfile }) => {
|
||||
const Availability: React.FC<AvailabilityProps> = ({ person }) => {
|
||||
const [availabilityHours, setAvailabilityHours] = useState<number>(0);
|
||||
const updateFN = () => setAvailabilityHours(person?.availability_hours || 0);
|
||||
const { animation } = useAnimation(person?.availability_hours, updateFN);
|
||||
const { animation } = useAnimateProfileChanges(
|
||||
person?.availability_hours,
|
||||
updateFN,
|
||||
);
|
||||
return (
|
||||
<Flex alignItems="center">
|
||||
<Box pr={2}>
|
||||
@@ -235,7 +238,10 @@ const TimeZoneDisplay: React.FC<TimeZoneDisplayProps> = ({ person }) => {
|
||||
if (timeDisplay.offset) setOffset(timeDisplay.offset);
|
||||
};
|
||||
|
||||
const { animation } = useAnimation(timeDisplay.timeZone, updateFN);
|
||||
const { animation } = useAnimateProfileChanges(
|
||||
timeDisplay.timeZone,
|
||||
updateFN,
|
||||
);
|
||||
return (
|
||||
<Flex alignItems="center">
|
||||
<Box pr={1}>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { MetaTag } from '@metafam/ds';
|
||||
import { FlexContainer } from 'components/Container';
|
||||
import { PlayerFragmentFragment } from 'graphql/autogen/types';
|
||||
import { useAnimation } from 'lib/hooks/players';
|
||||
import { useAnimateProfileChanges } from 'lib/hooks/players';
|
||||
import React, { useState } from 'react';
|
||||
|
||||
import { PlayerHeroTile } from './PlayerHeroTile';
|
||||
@@ -13,7 +13,7 @@ export const PlayerPronouns: React.FC<Props> = ({ person }) => {
|
||||
const updateFN = () => {
|
||||
setPronouns(person?.pronouns || '');
|
||||
};
|
||||
const { animation } = useAnimation(person?.pronouns, updateFN);
|
||||
const { animation } = useAnimateProfileChanges(person?.pronouns, updateFN);
|
||||
|
||||
return pronouns ? (
|
||||
<PlayerHeroTile title="Personal pronouns">
|
||||
|
||||
@@ -4,7 +4,8 @@ import {
|
||||
SkillCategory_Enum,
|
||||
} from 'graphql/autogen/types';
|
||||
import { SkillColors } from 'graphql/types';
|
||||
import React, { useEffect, useRef, useState } from 'react';
|
||||
import { useAnimateProfileChanges } from 'lib/hooks/players';
|
||||
import React, { useState } from 'react';
|
||||
import { BOX_TYPE } from 'utils/boxTypes';
|
||||
|
||||
import { ProfileSection } from '../../ProfileSection';
|
||||
@@ -22,34 +23,20 @@ export const PlayerSkills: React.FC<Props> = ({
|
||||
const [playerSkills, setPlayerSkills] = useState<
|
||||
{ id: number; name: string; category: SkillCategory_Enum }[]
|
||||
>([]);
|
||||
const [animation, setAnimation] = useState<string>('fadeIn');
|
||||
|
||||
const usePrevious = <T extends unknown>(value: T): T | undefined => {
|
||||
const ref = useRef<T>();
|
||||
useEffect(() => {
|
||||
ref.current = value;
|
||||
});
|
||||
return ref.current;
|
||||
};
|
||||
const previousSkills = usePrevious(playerSkills);
|
||||
|
||||
useEffect(() => {
|
||||
if (JSON.stringify(playerSkills) !== JSON.stringify(previousSkills)) {
|
||||
setAnimation('fadeOut');
|
||||
setTimeout(() => {
|
||||
if (player.skills) {
|
||||
setPlayerSkills(
|
||||
player.skills.map((s) => ({
|
||||
id: s.Skill.id,
|
||||
name: s.Skill.name,
|
||||
category: s.Skill.category,
|
||||
})),
|
||||
);
|
||||
}
|
||||
setAnimation('fadeIn');
|
||||
}, 400);
|
||||
const updateFN = () => {
|
||||
if (player.skills) {
|
||||
setPlayerSkills(
|
||||
player.skills.map((s) => ({
|
||||
id: s.Skill.id,
|
||||
name: s.Skill.name,
|
||||
category: s.Skill.category,
|
||||
})),
|
||||
);
|
||||
}
|
||||
}, [player, previousSkills, playerSkills]);
|
||||
};
|
||||
|
||||
const { animation } = useAnimateProfileChanges(player.skills, updateFN);
|
||||
|
||||
if (!player.skills?.length) {
|
||||
return null;
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { Text } from '@metafam/ds';
|
||||
import { Player_Type, PlayerFragmentFragment } from 'graphql/autogen/types';
|
||||
import React, { useEffect, useRef, useState } from 'react';
|
||||
import { useAnimateProfileChanges } from 'lib/hooks/players';
|
||||
import React, { useState } from 'react';
|
||||
import { BOX_TYPE } from 'utils/boxTypes';
|
||||
|
||||
import { FlexContainer } from '../../Container';
|
||||
@@ -18,31 +19,9 @@ export const PlayerType: React.FC<Props> = ({
|
||||
onRemoveClick,
|
||||
}) => {
|
||||
const [playerType, setPlayerType] = useState<Player_Type | null>();
|
||||
const [animation, setAnimation] = useState<string>('fadeIn');
|
||||
const updateFN = () => setPlayerType(player.type);
|
||||
|
||||
const type = player?.type;
|
||||
|
||||
const usePrevious = <T extends unknown>(value: T): T | undefined => {
|
||||
const ref = useRef<T>();
|
||||
useEffect(() => {
|
||||
ref.current = value;
|
||||
});
|
||||
return ref.current;
|
||||
};
|
||||
const previousType = usePrevious(type);
|
||||
|
||||
// todo refactor so that usePrevious won't be needed anymore
|
||||
// something is retriggering useEffect when color disposition is changed, for example
|
||||
// i suspect the type object's reference is changing
|
||||
useEffect(() => {
|
||||
if (previousType?.title !== type?.title) {
|
||||
setAnimation('fadeOut');
|
||||
setTimeout(() => {
|
||||
setPlayerType(type);
|
||||
setAnimation('fadeIn');
|
||||
}, 400);
|
||||
}
|
||||
}, [type, previousType]);
|
||||
const { animation } = useAnimateProfileChanges(player.type, updateFN);
|
||||
|
||||
return (
|
||||
<ProfileSection
|
||||
|
||||
@@ -297,19 +297,31 @@ const usePaginatedPlayers = (
|
||||
};
|
||||
};
|
||||
|
||||
export const useAnimation = (
|
||||
export const useAnimateProfileChanges = (
|
||||
depends: unknown,
|
||||
updateFN: () => void,
|
||||
): { [key: string]: string } => {
|
||||
const [animation, setAnimation] = useState('fadeIn');
|
||||
|
||||
const usePrevious = <T extends unknown>(value: T): T | undefined => {
|
||||
const ref = useRef<T>();
|
||||
useEffect(() => {
|
||||
ref.current = value;
|
||||
});
|
||||
return ref.current;
|
||||
};
|
||||
const previousValue = usePrevious(depends);
|
||||
|
||||
useEffect(() => {
|
||||
setAnimation('fadeOut');
|
||||
setTimeout(() => {
|
||||
updateFN();
|
||||
setAnimation('fadeIn');
|
||||
}, 400);
|
||||
}, [depends, updateFN]);
|
||||
if (JSON.stringify(previousValue) !== JSON.stringify(depends)) {
|
||||
setAnimation('fadeOut');
|
||||
setTimeout(() => {
|
||||
updateFN();
|
||||
setAnimation('fadeIn');
|
||||
}, 400);
|
||||
}
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [depends]);
|
||||
|
||||
return { animation };
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user