#reactjs #material-ui #state #array.prototype.map
#javascript #reactjs #material-ui #состояние #array.prototype.map
Вопрос:
Я успешно реализовал вкладки Material UI путем жесткого кодирования содержимого, но когда я попытался создать свои жестко закодированные вкладки с помощью функции .map для заполнения содержимого из источника данных (простой json), он больше не работает. Кто-нибудь может понять, почему? Единственное изменение, которое я внес, было в компонент MyTabs ниже, где теперь есть две функции .map вместо жестко закодированных вкладок.
Большое спасибо за вашу помощь!
Вот мои данные:
export const TabsData = [
{
tabTitle: 'Tab 1',
tabContent: 'Hello 1',
},
{
tabTitle: 'Tab 2',
tabContent: 'Hello 2',
},
{
tabTitle: 'Tab 3',
tabContent: 'Hello 3',
},
];
Вот мой компонент MyTabs:
import React, { useState } from 'react';
// Material UI
import Tabs from '@material-ui/core/Tabs';
import Tab from '@material-ui/core/Tab';
// Data
import { TabsData } from '../../page-templates/full-page-with-tabs/FullPageWithTabsData';
//Components
import TabContentPanel from '../tabs/tab-content-panel/TabContentPanel';
const MyTabs = () => {
const classes = useStyles();
const initialTabIndex = 0;
const [value, setValue] = useState(initialTabIndex);
const handleChange = (event, newValue) => {
setValue(newValue);
};
return (
<>
<Tabs
value={value}
onChange={handleChange}
aria-label=""
className={classes.tabHeight}
classes={{ indicator: classes.indicator }}
>
{TabsData.map((tabInfo, index) => (
<>
<Tab
label={tabInfo.tabTitle}
id={`simple-tab-${index}`}
ariaControls={`simple-tabpanel-${index}`}
/>
</>
))}
</Tabs>
{TabsData.map((tabInfo, index) => (
<TabContentPanel value={value} index={index}>
{tabInfo.tabContent}
</TabContentPanel>
))}
</>
);
};
export default MyTabs;
А вот и компонент TabsPanel:
import React from 'react';
import PropTypes from 'prop-types';
// Material UI
import { Box } from '@material-ui/core';
function TabContentPanel(props) {
const { children, value, index, ...other } = props;
const classes = useStyles();
return (
<div
role="tabpanel"
hidden={value !== index}
id={`simple-tabpanel-${index}`}
aria-labelledby={`simple-tab-${index}`}
{...other}
>
{value === index amp;amp; <Box className={classes.contentContainer}>{children}</Box>}
</div>
);
}
TabContentPanel.propTypes = {
children: PropTypes.node,
index: PropTypes.any.isRequired,
value: PropTypes.any.isRequired,
};
export default TabContentPanel;
Ответ №1:
Это не работает, потому что вы добавили дополнительные Fragment
s ( <>
и </>
) в Tabs
компонент, а Tabs
компонент не принимает a Fragment
как дочерний элемент:
Если вы удалите их, все будет работать так, как ожидалось:
{TabsData.map((tabInfo, index) => (
<Tab
label={tabInfo.tabTitle}
id={`simple-tab-${index}`}
key={tabInfo.tabTitle}
ariaControls={`simple-tabpanel-${index}`}
/>
))}
И, пожалуйста, используйте key
prop с уникальным идентификатором, если вы создаете массив элементов. У каждого дочернего элемента в списке должен быть уникальный «ключевой» реквизит.
Комментарии:
1. У-у-у! Теперь это работает отлично! Большое вам спасибо за вашу помощь и за дополнительные советы по включению ключа. Очень признателен и избавил меня от траты времени на попытки разобраться в этом! 🙂