Skip to content

Commit

Permalink
perf(GoalsGroup): fix memoization
Browse files Browse the repository at this point in the history
  • Loading branch information
KateKate committed Aug 31, 2023
1 parent 20bc5d9 commit bb0b44a
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 33 deletions.
24 changes: 2 additions & 22 deletions src/components/DashboardPage/DashboardPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
import React, { MouseEventHandler, useCallback, useEffect } from 'react';
import styled from 'styled-components';
import dynamic from 'next/dynamic';
import NextLink from 'next/link';
import { useRouter } from 'next/router';
import { nullable, Button, Table } from '@taskany/bricks';
import { gapSm } from '@taskany/colors';
Expand All @@ -15,20 +14,17 @@ import { createFilterKeys } from '../../utils/hotkeys';
import { useUrlFilterParams } from '../../hooks/useUrlFilterParams';
import { useFilterResource } from '../../hooks/useFilterResource';
import { useFiltersPreset } from '../../hooks/useFiltersPreset';
import { routes } from '../../hooks/router';
import { Page, PageContent } from '../Page';
import { CommonHeader } from '../CommonHeader';
import { FiltersPanel } from '../FiltersPanel/FiltersPanel';
import { GoalsGroup } from '../GoalsGroup';
import { Nullish } from '../../types/void';
import { trpc } from '../../utils/trpcClient';
import { FilterById, GoalByIdReturnType } from '../../../trpc/inferredTypes';
import { ProjectListItem } from '../ProjectListItem';
import { PageTitlePreset } from '../PageTitlePreset/PageTitlePreset';
import { useGoalPreview } from '../GoalPreview/GoalPreviewProvider';
import { InlineTrigger } from '../InlineTrigger';
import { useFMPMetric } from '../../utils/telemetry';
import { WrappedRowLink } from '../WrappedRowLink';

import { tr } from './DashboardPage.i18n';

Expand Down Expand Up @@ -200,24 +196,8 @@ export const DashboardPage = ({ user, ssrTime, defaultPresetFallback }: External
selectedResolver={selectedGoalResolver}
onClickProvider={onGoalPrewiewShow}
onTagClick={setTagsFilterOutside}
>
<Table>
<NextLink href={routes.project(group.project.id)} passHref legacyBehavior>
<WrappedRowLink>
<ProjectListItem
key={group.project.id}
title={group.project.title}
owner={group.project?.activity}
participants={group.project?.participants}
starred={group.project?._isStarred}
watching={group.project?._isWatching}
averageScore={group.project?.averageScore}
/>
</WrappedRowLink>
</NextLink>
</Table>
</GoalsGroup>

project={group.project}
/>
{!group.goals.length && (
<StyledInlineTriggerWrapper>
<InlineTrigger
Expand Down
51 changes: 42 additions & 9 deletions src/components/GoalsGroup.tsx
Original file line number Diff line number Diff line change
@@ -1,21 +1,35 @@
/* eslint-disable prefer-arrow-callback */
import React, { MouseEventHandler } from 'react';
import styled from 'styled-components';
import { gapM, gapS } from '@taskany/colors';
import { Table } from '@taskany/bricks';
import NextLink from 'next/link';

import { GoalByIdReturnType } from '../../trpc/inferredTypes';
import { ActivityByIdReturnType, GoalByIdReturnType } from '../../trpc/inferredTypes';
import { routes } from '../hooks/router';

import { GoalListItem } from './GoalListItem';
import { PageSep } from './PageSep';
import { TableFullWidthCell } from './Table';
import { WrappedRowLink } from './WrappedRowLink';
import { ProjectListItem } from './ProjectListItem';

interface GoalGroupProps {
type GoalGroupProps = {
goals: NonNullable<GoalByIdReturnType>[];
children: React.ReactNode;
selectedResolver: (id: string) => boolean;

onClickProvider: (g: NonNullable<GoalByIdReturnType>) => MouseEventHandler<HTMLAnchorElement>;
onTagClick?: React.ComponentProps<typeof GoalListItem>['onTagClick'];
}
project: {
id: string;
title: string;
averageScore: number | null;
activity?: ActivityByIdReturnType;
participants?: ActivityByIdReturnType[];
_isStarred?: boolean;
_isWatching?: boolean;
};
};

const GoalsGroupContainer = styled(TableFullWidthCell)`
padding-top: ${gapM};
Expand All @@ -29,11 +43,30 @@ const GolasGroupSep = styled(PageSep)`
margin: ${gapS} 0px;
`;

export const GoalsGroup: React.FC<GoalGroupProps> = React.memo(
({ goals, children, selectedResolver, onClickProvider, onTagClick }) => (
export const GoalsGroup = React.memo<GoalGroupProps>(function GoalsGroup({
goals,
selectedResolver,
onClickProvider,
onTagClick,
project,
}) {
return (
<>
<GoalsGroupContainer>
{children}
<Table>
<NextLink href={routes.project(project.id)} passHref legacyBehavior>
<WrappedRowLink>
<ProjectListItem
title={project.title}
owner={project.activity}
participants={project.participants}
starred={project._isStarred}
watching={project._isWatching}
averageScore={project.averageScore}
/>
</WrappedRowLink>
</NextLink>
</Table>
<GolasGroupSep />
</GoalsGroupContainer>

Expand Down Expand Up @@ -62,5 +95,5 @@ export const GoalsGroup: React.FC<GoalGroupProps> = React.memo(
/>
))}
</>
),
);
);
});
6 changes: 4 additions & 2 deletions src/hooks/useUrlFilterParams.ts
Original file line number Diff line number Diff line change
Expand Up @@ -118,8 +118,10 @@ export const useUrlFilterParams = ({ preset }: { preset?: FilterById }) => {
const router = useRouter();
const [currentPreset, setCurrentPreset] = useState(preset);
const [prevPreset, setPrevPreset] = useState(preset);
const query = currentPreset ? Object.fromEntries(new URLSearchParams(currentPreset.params)) : router.query;
const queryState = useMemo<QueryState>(() => parseFilterValues(query), [query]);
const queryState = useMemo<QueryState>(() => {
const query = currentPreset ? Object.fromEntries(new URLSearchParams(currentPreset.params)) : router.query;
return parseFilterValues(query);
}, [router.query, currentPreset]);
const queryString = router.asPath.split('?')[1];

if (prevPreset?.id !== preset?.id || prevPreset?._isStarred !== preset?._isStarred) {
Expand Down

0 comments on commit bb0b44a

Please sign in to comment.