Refactoring - Extracting a Query Object
随着项目复杂度提高,将会有越来越多的查询参数,是时候把他们封装成一个对象。
App.tsx |
---|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53 | import { Grid, GridItem, Show } from "@chakra-ui/react";
import NavBar from "./components/NavBar";
import GameGrid from "./components/GameGrid";
import GenreList from "./components/GenreList";
import { useState } from "react";
import { Genre } from "./hooks/useGenres";
import PlatfromSelector from "./components/PlatfromSelector";
import { Platform } from "./hooks/useGames";
export interface GameQuery {
genre: Genre | null;
platform: Platform | null;
}
function App() {
const [gameQuery, setGameQuery] = useState<GameQuery>({} as GameQuery);
return (
<Grid
templateAreas={{
base: `"nav" "main"`,
lg: `"nav nav" "aside main"`,
}}
templateColumns={{
base: "1fr",
lg: "250px 1fr",
}}
>
<GridItem area="nav">
<NavBar />
</GridItem>
<Show above="lg">
<GridItem area="aside" paddingX={5}>
<GenreList
onSelectGenre={(genre) => setGameQuery({ ...gameQuery, genre })}
selectedGenre={gameQuery.genre}
/>
</GridItem>
</Show>
<GridItem area="main">
<PlatfromSelector
onSelectPlatform={(platform) =>
setGameQuery({ ...gameQuery, platform })
}
selectedPlatform={gameQuery.platform}
/>
<GameGrid gameQuery={gameQuery} />
</GridItem>
</Grid>
);
}
export default App;
|
由于查询参数跟接口息息相关,因此还是会涉及到 GameGrid > useGame
GameGird.tsx |
---|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42 | import { Text, SimpleGrid, Skeleton } from "@chakra-ui/react";
import useGames, { Platform } from "../hooks/useGames";
import GameCard from "./GameCard";
import GameCardSkeleton from "./GameCardSkeleton";
import GameCardContainer from "./GameCardContainer";
import { Genre } from "../hooks/useGenres";
import { GameQuery } from "../App";
interface Props {
gameQuery: GameQuery;
}
const GameGrid = ({ gameQuery }: Props) => {
const { data, error, isLoading } = useGames(gameQuery);
const skeletons = [1, 2, 3, 4, 5, 6];
// Array.from({ length: data.length + 1 }, (_, i) => i++);
return (
<>
{error && <Text>{error}</Text>}
<SimpleGrid
columns={{ sm: 1, md: 2, lg: 3, xl: 5 }}
padding="10px"
spacing={3}
>
{isLoading &&
skeletons.map((Skeleton) => (
<GameCardContainer key={Skeleton}>
<GameCardSkeleton />
</GameCardContainer>
))}
{data.map((game) => (
<GameCardContainer key={game.id}>
<GameCard game={game} />
</GameCardContainer>
))}
</SimpleGrid>
</>
);
};
export default GameGrid;
|
useGame.tsx |
---|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31 | import { GameQuery } from "../App";
import useData from "./useData";
import { Genre } from "./useGenres";
export interface Platform {
id: number;
name: string;
slug: string;
}
export interface Game {
id: number;
name: string;
metacritic: number;
background_image: string;
parent_platforms: { platform: Platform }[];
}
const useGames = (gameQuery: GameQuery) =>
useData<Game>(
"/games",
{
params: {
genres: gameQuery.genre?.id,
platforms: gameQuery.platform?.id,
},
},
[gameQuery]
);
export default useGames;
|
2024-08-18 17:24 2024-08-18 21:25