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} />