跳转至

Custom Hooks

Creating a Custom Hooks for Fetching the Games#

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
└── 📁src
    └── App.css
    └── App.tsx
    └── 📁assets
        └── logo.webp
        └── react.svg
    └── 📁components
        └── ColorModeSwitch.tsx
        └── GameGrid.tsx
        └── NavBar.tsx
    └── 📁hooks
        └── useGames.ts
    └── index.css
    └── main.tsx
    └── 📁services
        └── api-client.ts
    └── theme.ts
    └── vite-env.d.ts

这里只是将 useEffect 钩子改成模块化结构,而不是封装为通用的组件在各个组件内调用。

api-client 用来专门配置 ajax 请求。

api-client.ts
1
2
3
4
5
6
7
8
import axios from "axios";

export default axios.create({
  baseURL: "https://api.rawg.io/api",
  params: {
    key: "14cdb9d729944e8db6f524d1f9b91b66",
  },
});

将所有与 Game 相关的内容放在自定义的 hooks 内。

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

export interface Game {
  id: number;
  name: string;
}

export interface FetchGamesResponse {
  count: number;
  results: Game[];
}

const useGames = () => {
  const [games, setGames] = useState<Game[]>([]);
  const [error, setError] = useState("");
  const controller = new AbortController();

  useEffect(() => {
    apiClient
      .get<FetchGamesResponse>("/games", { signal: controller.signal })
      .then((res) => setGames(res.data.results))
      .catch((err) => {
        if (err instanceof CanceledError) return;
        setError(err.message);
      });
    return () => controller.abort();
  }, []);

  return { games, error };
};

export default useGames;

修改原来的

GameGrid.tsx
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
import { Text } from "@chakra-ui/react";
import useGames from "../hooks/useGames";

const GameGrid = () => {
  const { games, error } = useGames();

  return (
    <>
      {error && <Text>{error}</Text>}
      <ul>
        {games.map((game) => (
          <li key={game.id}>{game.name}</li>
        ))}
      </ul>
    </>
  );
};

export default GameGrid;

2024-07-12 23:44 2024-07-13 15:26

评论