refactor(BattleTable): extract resultMap logic and simplify table building
- Move `initResultMap` and `buildMatchGroupTable` outside the component to reduce closure dependencies. - Update `ClubEventList` to remove obsolete page key storage logic. - Add `MATCH_RESULT_MAP_KEY` constant to `utils/constants.ts`. - Refactor `useMemo` and `useCallback` hooks to rely on the extracted functions. - Ensure consistent dependency arrays in callbacks for reliable re-renders.
This commit is contained in:
parent
ce5c523efb
commit
f29974c111
@ -6,6 +6,7 @@ import styled from "styled-components";
|
||||
import { cloneDeep } from "lodash";
|
||||
import { ClearOutlined, EditOutlined, ShareAltOutlined } from "@ant-design/icons";
|
||||
import { useLocation } from "react-router";
|
||||
import { MATCH_RESULT_MAP_KEY } from "../utils/constants";
|
||||
|
||||
const StyledContainer = styled(Flex)`
|
||||
min-width: 300px;
|
||||
@ -30,31 +31,16 @@ function getMatchKey(player1: BasePlayer, player2: BasePlayer) {
|
||||
return `${player1.uid}-${player2.uid}`;
|
||||
}
|
||||
|
||||
function BattleTable({
|
||||
players: list,
|
||||
}: {
|
||||
players: BasePlayer[];
|
||||
}) {
|
||||
const playerList = useMemo(() => list.length % 2 === 0 ? list : [...list, {
|
||||
uid: '',
|
||||
score: '',
|
||||
name: '-',
|
||||
}], [list]);
|
||||
const resultMap = useMemo(() => {
|
||||
function initResultMap() {
|
||||
const cache = localStorage.getItem('match-result-map');
|
||||
const cacheEntries: [string, Result][] = cache ? Object.entries(JSON.parse(cache)) : [];
|
||||
return new Map<string, {
|
||||
winer: string,
|
||||
score: number,
|
||||
}>(cacheEntries);
|
||||
}, []);
|
||||
useEffect(() => {
|
||||
return () => {
|
||||
const cache = JSON.stringify(Object.fromEntries(resultMap.entries()));
|
||||
localStorage.setItem('match-result-map', cache);
|
||||
}
|
||||
}, [resultMap]);
|
||||
const buildMatchGroupTable = useCallback((list: (BasePlayer | null)[]) => {
|
||||
}
|
||||
|
||||
const buildMatchGroupTable = (list: (BasePlayer | null)[], resultMap: Map<string, Result>) => {
|
||||
const roundNum = list.length - 1;
|
||||
const dataList = cloneDeep(list);
|
||||
const roundTable = new Array(roundNum).fill(0).map((_, i) => {
|
||||
@ -76,8 +62,22 @@ function BattleTable({
|
||||
});
|
||||
return cloneDeep([left, right]);
|
||||
});
|
||||
const cache = JSON.stringify(Object.fromEntries(resultMap.entries()));
|
||||
localStorage.setItem(MATCH_RESULT_MAP_KEY, cache);
|
||||
return roundTable;
|
||||
}, []);
|
||||
};
|
||||
|
||||
function BattleTable({
|
||||
players: list,
|
||||
}: {
|
||||
players: BasePlayer[];
|
||||
}) {
|
||||
const playerList = useMemo(() => list.length % 2 === 0 ? list : [...list, {
|
||||
uid: '',
|
||||
score: '',
|
||||
name: '-',
|
||||
}], [list]);
|
||||
const resultMap = useMemo(() => initResultMap(), []);
|
||||
const [matchGroupTable, setMatchGroupTable] = useState<ReturnType<typeof buildMatchGroupTable>>([]);
|
||||
const matchKeys = useMemo(() => {
|
||||
const keys: string[] = [];
|
||||
@ -99,16 +99,16 @@ function BattleTable({
|
||||
} else {
|
||||
resultMap.set(key, { winer: winer?.uid!, score });
|
||||
}
|
||||
setMatchGroupTable(buildMatchGroupTable(playerList));
|
||||
}, []);
|
||||
setMatchGroupTable(buildMatchGroupTable(playerList, resultMap));
|
||||
}, [playerList, resultMap]);
|
||||
const handleClear = useCallback((left?: (BasePlayer | null | undefined)[], right?: (BasePlayer | null | undefined)[]) => {
|
||||
left?.forEach((l, i) => {
|
||||
const r = right?.[i];
|
||||
const key = getMatchKey(l!, r!);
|
||||
resultMap.delete(key);
|
||||
});
|
||||
setMatchGroupTable(buildMatchGroupTable(playerList));
|
||||
}, [matchGroupTable, playerList]);
|
||||
setMatchGroupTable(buildMatchGroupTable(playerList, resultMap));
|
||||
}, [playerList, resultMap]);
|
||||
const handleClearAll = useCallback(() => {
|
||||
matchGroupTable.forEach(([left, right]) => {
|
||||
left?.forEach((l, i) => {
|
||||
@ -117,8 +117,8 @@ function BattleTable({
|
||||
resultMap.delete(key);
|
||||
});
|
||||
});
|
||||
setMatchGroupTable(buildMatchGroupTable(playerList));
|
||||
}, [matchGroupTable, playerList]);
|
||||
setMatchGroupTable(buildMatchGroupTable(playerList, resultMap));
|
||||
}, [matchGroupTable, playerList, resultMap]);
|
||||
const scoreDiff = useMemo(() => {
|
||||
const [left = [], right = []] = matchGroupTable?.[matchGroupTable.length - 1] ?? [];
|
||||
const newScoreMap = Object.fromEntries([...left, ...right].map(e => [e?.uid, e?.score]));
|
||||
@ -154,9 +154,9 @@ function BattleTable({
|
||||
setImportModalVisible(false);
|
||||
}, []);
|
||||
useEffect(() => {
|
||||
const roundTable = buildMatchGroupTable(playerList);
|
||||
const roundTable = buildMatchGroupTable(playerList, resultMap);
|
||||
setMatchGroupTable(roundTable);
|
||||
}, [playerList]);
|
||||
}, [playerList, resultMap]);
|
||||
const [shareCode, setShareCode] = useState('');
|
||||
const handleImportCode = useCallback(async () => {
|
||||
const data: Record<string, Result> = await fetch(`/api/battle/${eventId}?code=${shareCode}`)
|
||||
@ -166,7 +166,7 @@ function BattleTable({
|
||||
const { winer = '', score = 0 } = v ?? {};
|
||||
resultMap.set(k, { winer, score });
|
||||
});
|
||||
setMatchGroupTable(buildMatchGroupTable(playerList));
|
||||
setMatchGroupTable(buildMatchGroupTable(playerList, resultMap));
|
||||
setImportModalVisible(false);
|
||||
}, [shareCode, playerList]);
|
||||
// console.debug('matchGroupTable', matchGroupTable, gameResultMap);
|
||||
|
||||
@ -4,7 +4,6 @@ import { useCallback, useEffect, useMemo, useState } from "react";
|
||||
import { EventCard } from "./EventCard";
|
||||
import { useRequest } from "ahooks";
|
||||
import { CalendarOutlined } from "@ant-design/icons";
|
||||
import { STORE_PAGE_LIST_KEY } from "../utils/constants";
|
||||
|
||||
interface Props {
|
||||
clubId: string;
|
||||
@ -44,11 +43,6 @@ export const ClubEvenList = (props: Props) => {
|
||||
}, [showFinishedEvents, requestEvents.data?.data]);
|
||||
const onPageInit = useCallback(async () => {
|
||||
const storePageKey = getStorageKey(props.clubId);
|
||||
const keys: string[] = JSON.parse(localStorage.getItem(STORE_PAGE_LIST_KEY) ?? '[]');
|
||||
if (!keys.includes(storePageKey)) {
|
||||
keys.push(storePageKey);
|
||||
localStorage.setItem(STORE_PAGE_LIST_KEY, JSON.stringify(keys));
|
||||
}
|
||||
const prePage = Number(sessionStorage.getItem(storePageKey)) || 1;
|
||||
const data = await requestEvents.runAsync(props.clubId, prePage).then(res => res.data);
|
||||
setPage(prePage);
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
export const LOGTO_RESOURCE = 'https://tt.ksr.la';
|
||||
export const CLUB_SELECTOR_KEY = 'CLUB_SELECTOR';
|
||||
export const STORE_PAGE_LIST_KEY = 'events-page-keys';
|
||||
export const MATCH_RESULT_MAP_KEY = 'match-result-map';
|
||||
Loading…
Reference in New Issue
Block a user