Displaying Platform Icons

One of the Game Object
 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
{
  "id": 3498,
  "slug": "grand-theft-auto-v",
  "name": "Grand Theft Auto V",
  "released": "2013-09-17",
  "tba": false,
  "background_image": "https://media.rawg.io/media/games/20a/20aa03a10cda45239fe22d035c0ebe64.jpg",
  "rating": 4.47,
  "rating_top": 5,
  "ratings": [{}, {}, {}, {}],
  "ratings_count": 6836,
  "reviews_text_count": 62,
  "added": 21042,
  "added_by_status": {},
  "metacritic": 92,
  "playtime": 74,
  "suggestions_count": 434,
  "updated": "2024-07-19T19:20:24",
  "user_game": null,
  "reviews_count": 6942,
  "saturated_color": "0f0f0f",
  "dominant_color": "0f0f0f",
  "platforms": [{}, {}, {}, {}, {}, {}, {}],
  "parent_platforms": [{}, {}, {}],
  "genres": [{}],
  "stores": [{}, {}, {}, {}, {}],
  "clip": null,
  "tags": [
    {},
    {},
    {},
    {},
    {},
    {},
    {},
    {},
    {},
    {},
    {},
    {},
    {},
    {},
    {},
    {},
    {},
    {},
    {}
  ],
  "esrb_rating": {},
  "short_screenshots": [{}, {}, {}, {}, {}, {}, {}]
}

如果要展示游戏上架平台图标,需要用到返回的 parent_platforms 属性。而 platforms 更加细化。比如 parent_platforms 是 PlayStation,那么 platforms 可能就包含 PS 4、PS 5。

parent_platform
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
[
  {
    "platform": {
      "id": 1,
      "name": "PC",
      "slug": "pc"
    }
  },
  {
    "platform": {
      "id": 2,
      "name": "PlayStation",
      "slug": "playstation"
    }
  },
  {
    "platform": {
      "id": 3,
      "name": "Xbox",
      "slug": "xbox"
    }
  }
]

parent_platforms 是储存 platform 对象的列表,因此需要对 Game 的类型新增标注:

useGame.ts
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
export interface Platform {
  id: number;
  name: string;
  slug: string;
}

export interface Game {
  id: number;
  name: string;
  background_image: string;
  parent_platforms: { platform: Platform }[];
}

CTRL+T 可以搜索函数、类和组件等。

回到 GameCard.tsx 中,先尝试输出 parent_platforms 中的平台名称。

GameCard.tsx
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
...
const GameCard = ({ game }: Props) => {
  return (
    <Card borderRadius="10px" overflow="hidden">
      <Image src={game.background_image} />
      <CardBody>
        <Heading fontSize="2xl">{game.name}</Heading>
        {game.parent_platforms.map(({platform}) => <Text>{platform.game}</Text>)}
      </CardBody>
    </Card>
  );
};
...

接下来便是使用 React Icons 库显示图标,npm i react-icons@4.7.1

由于渲染图标的逻辑与 GameCard 定位不符,因此需要新建一个组件 PlatformIconList.tsx 用于专门负责渲染游戏平台的图标。

PlatformIconList.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
import {
  FaWindows,
  FaPlaystation,
  FaXbox,
  FaApple,
  FaLinux,
  FaAndroid,
} from "react-icons/fa";
import { MdPhoneIphone } from "react-icons/md";
import { SiNintendo } from "react-icons/si";
import { BsGlobe } from "react-icons/bs";

import { Platform } from "../hooks/useGames";
import { Icon, HStack } from "@chakra-ui/react";
import { IconType } from "react-icons";
interface Props {
  platforms: Platform[];
}

const PlatformIconList = ({ platforms }: Props) => {
  const iconMap: { [key: string]: IconType } = {
    pc: FaWindows,
    playstation: FaPlaystation,
    xbox: FaXbox,
    nintendo: SiNintendo,
    mac: FaApple,
    linux: FaLinux,
    android: FaAndroid,
    ios: MdPhoneIphone,
    web: BsGlobe,
  };
  return (
    <HStack marginY={1}>
      {platforms.map((platform) => (
        <Icon as={iconMap[platform.slug]} color="gray.500" />
      ))}
    </HStack>
  );
};

export default PlatformIconList;

索引签名(Index Signature)允许你定义对象属性的键和值的类型。

语法:

{ [key: KeyType]: ValueType }

const iconMap: { [key: string]: IconType } = {} 为例:

  • iconMap 是一个对象,具有动态的键和值。
  • { [key: string]: IconType } 是类型注解,表示 iconMap 对象的键是字符串类型,值是 IconType 类型。
  • IconType 是一个类型别名或者接口,代表某种图标类型。

2024-07-20 15:10 2024-07-20 16:11

评论