Fetching the Genres

API: https://api.rawg.io/api/genres

genres response samples
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
{
  "count": 0,
  "next": "http://example.com",
  "previous": "http://example.com",
  "results": [
    {
      "id": 0,
      "name": "string",
      "slug": "string",
      "games_count": 0,
      "image_background": "http://example.com"
    }
  ]
}

在 hooks 文件夹新建一个 useGenres.ts,专门负责请求分类,其内容与 useGames 类似,可以直接复制进来再修改。

 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
import { CanceledError } from "axios";
import apiClient from "../services/api-client";
import { useEffect, useState } from "react";

interface Genre {
  id: number;
  name: string;
  slug: string;
  image_background: string;
}

interface FetchGenresResponse {
  count: number;
  results: Genre[];
}

const useGenres = () => {
  const [genres, setGenres] = useState<Genre[]>([]);
  const [error, setError] = useState("");
  const [isLoading, setLoading] = useState(false);
  useEffect(() => {
    const controller = new AbortController();

    setLoading(true);

    apiClient
      .get<FetchGenresResponse>("/genres", { signal: controller.signal })
      .then((res) => {
        setGenres(res.data.results);
        setLoading(false);
      })
      .catch((err) => {
        if (err instanceof CanceledError) return;
        {
          setError(err.message);
          setLoading(false);
        }
      });
    return () => controller.abort();
  }, []);

  return { genres, error, isLoading };
};

export default useGenres;

然后在 GenreList 组件中使用该 hook 来获得 genres 对象:

GenreList.tsx
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
import useGenres from "../hooks/useGenres";
const GenreList = () => {
  const { genres } = useGenres();

  return (
    <div>
      {genres.map((genre) => (
        <ul key={genre.id}>{genre.name}</ul>
      ))}
    </div>
  );
};

export default GenreList;

最后 App.tsx 中把该组件放上去:

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
import { Grid, GridItem, Show } from "@chakra-ui/react";
import NavBar from "./components/NavBar";
import GameGrid from "./components/GameGrid";
import GenreList from "./components/GenreList";

function App() {
  return (
    <Grid
      templateAreas={{
        base: `"nav" "main"`,
        lg: `"nav nav" "aside main"`,
      }}
    >
      <GridItem area="nav">
        <NavBar />
      </GridItem>
      <Show above="lg">
        <GridItem area="aside" bg="gold">
          <GenreList />
        </GridItem>
      </Show>
      <GridItem area="main" bg="dodgerblue">
        <GameGrid />
      </GridItem>
    </Grid>
  );
}

export default App;

2024-07-21 20:09 2024-07-21 23:49

评论