/

React,如何動態選擇要渲染的組件

React,如何動態選擇要渲染的組件

我有一個需求,需要在菜單中渲染一個項目列表,每個項目都有自己的圖標。

起初,我在菜單中硬編碼組件,像這樣:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
const menu = [
{
title: '首頁',
icon: <HomeIcon className="mr-3 ml-1 h-5 w-5" />
},
{
title: '通知',
icon: <BellIcon className="mr-3 ml-1 h-5 w-5" />
},
{
title: '個人資料',
icon: <UserIcon className="mr-3 ml-1 h-5 w-5" />
},
];

使用非常酷的 @heroicons/react 套件。

在 JSX 中,我使用 menu 陣列迭代顯示 {item.icon}

但是,後來我需要根據應用程序的響應狀態更改使用的 Tailwind 類,所以我使用了 react-responsive 套件。

我決定改為傳遞一個字符串,因此首先做了這個更改:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
const menu = [
{ title: '首頁', icon: 'HomeIcon' },
{ title: '通知', icon: 'BellIcon' },
{ title: '個人資料', icon: 'UserIcon' },
];

const Icon = (props) => {
const { name } = props;

let icon = null;
if (name === 'HomeIcon') icon = HomeIcon;
if (name === 'BellIcon') icon = BellIcon;
if (name === 'UserIcon') icon = UserIcon;

return React.createElement(icon, { ...props });
};

...

<Icon name={item.icon} />

另一種解決方案是使用物件查找組件,而不是一堆 if 檢查:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
const icons = {
HomeIcon,
BellIcon,
UserIcon,
};

const Icon = (props) => {
const { name } = props;

const TheIcon = icons[name];
return <TheIcon {...props} />;
};

<Icon name={item.icon} />

我必須使用 TheIcon,因為 React 組件以大寫字母開頭是一種約定。

這樣已經足夠好了,但後來我意識到可以以更簡潔的方式來實現,直接在 menu 陣列中使用實際的組件而不是字符串:

const menu = [
  { title: '首頁', icon: HomeIcon },
  { title: '通知', icon: BellIcon },
  { title: '個人資料', icon: UserIcon },
];

const Icon = (props) => {
  const { icon } = props;
  const TheIcon = icon;
  return <TheIcon {...props} />;
};

...

<Icon icon={item.icon} />