- 元件載入時: B -> D -> E -> A -> C -> B -> D -> A
- 按下按鈕: D -> E -> A
- 請估算 getTeamLeaderInformation 的平均時間複雜度: O(n ^ 4)
- 並針對 Table 整體加以改善,並加以說明:
- 發現原本的
getTeamLeaderInformation
整體是針對 id
去找到對應的 leader,且會根據 userTableData
資料多寡來決定被 call 的次數。但其實可以先準備好 user 與 team 的相關資料。
- 根據上述,我在
fetchData
後,整理出帶有 team 資訊的 user 資料。將 team 資料范式化,直接透過 teamId
去找到對應資訊,無需額外遍歷 teams
。
- 將整理出的資料拿去 render,並也將 user 資料范式化,即可透過 user id 取得相關資訊。
import React, { useEffect, useMemo, useState } from 'react';
import { getAllTeamData, getAllUserData } from './data';
type UserData = {
teamId: string;
id: string;
name: string;
title: string;
teamName: string;
leaderId: string;
};
function convertArrayToObject<T>(ary: T[], key: string) {
return ary.reduce<Record<string, T>>(
(acc, cur) => ({
...acc,
[cur[key]]: cur,
}),
{}
);
}
const Table: React.VFC = () => {
const [userData, setUserData] = useState<UserData[]>([]);
const userMap = useMemo(
() => convertArrayToObject(userData, 'id'),
[userData]
);
useEffect(function getDataFromAPI() {
const fetchData = async () => {
const users: UserTableData = await getAllUsersData();
const teams: TeamTableData = await getAllTeamsData();
const teamsMap = convertArrayToObject(teams, 'id');
const nextUserData = users.map(user => {
const { teamId } = user;
const team = teamsMap[teamId];
return { ...user, leaderId: team.leader, teamName: team.name };
});
setUserData(nextUserData);
};
fetchData();
}, []);
return (
<table>
<thead>
<tr>
<th>ID</th>
<th>Name</th>
<th>Title</th>
<th>Team</th>
<th>Team Leader/</th>
</tr>
</thead>
<tbody>
{userData.map(user => {
return (
<tr key={user.id}>
<td>{user.id}</td>
<td>{user.name}</td>
<td>{user.title}</td>
<td>{user.teamName}</td>
<td>
<Tooltip label={userMap[user.leaderId]}>
{userMap[user.leaderId].name}
</Tooltip>
</td>
</tr>
);
})}
</tbody>
</table>
);
};
export default Table;