Мне нужна помощь по ReactJS и коду Typescript с использованием material-ui.
Я хочу переделать систему вкладок, предложенную по следующей ссылке, создав собственные имена компонентов: https://material-ui.com/components/tabs/#simple -tabs .
Вот код, который я сделал: https://codepen.io/Answerrer/pen/wvKLLzg.
interface MyTabPanelProperties {
label: string;
value: number;
index: number;
children?: React.ReactNode;
}
type MyTabPanelState = {}
class MyTabPanel extends React.Component<MyTabPanelProperties, MyTabPanelState> {
render(): JSX.Element {
const { children, value, index } = this.props;
const element = (
<div role="tabpanel" hidden={value !== index} aria-labelledby={'simple-tab'}>
{children}
</div>
);
return element;
}
}
interface MyTabsProperties<T = MyTabPanelProperties> {
value?: number;
children: React.ReactElement<T> | Array<React.ReactElement<T>> | React.Component<T> | Array<React.Component<T>>;
}
interface MyTabsState {
value: number;
}
class MyTabs extends React.Component<MyTabsProperties, MyTabsState> {
constructor(props: MyTabsProperties) {
super(props);
this.state = {
value: this.props.value ? this.props.value : 0
};
}
private checkChildrenName(children: ReactNode, names: string | Array<string>): boolean {
const childs = React.Children.toArray(children);
let check = false,
allNames = new Array<string>();
if (names instanceof Array) {
allNames = names;
} else {
allNames = names.split(' ');
}
if (allNames.length === 0) {
throw Error('Must specify names for check children');
}
check = childs.every((child) => {
let check = false;
const name = this.getComponentChildName(child);
if (name) {
check = allNames.includes(name);
}
return check;
});
return check;
}
private getComponentChildName(component: any): string | undefined {
const type = (component.type || {});
let name = undefined;
if (component) {
name = component.displayName ||
component.name ||
type.displayName ||
type.name ||
undefined;
}
return name;
}
render(): JSX.Element {
const { children } = this.props;
let element: JSX.Element;
if (this.checkChildrenName(children, 'MyTabPanel')) {
element = (
<div>
<AppBar position='static'>
<Tabs value='0' onChange={this.handleChange.bind(this)}>
{React.Children.map(children, (child, index) => {
return this.renderAppBarTab(child, index);
})}
</Tabs>
</AppBar>
{children}
</div>
);
} else {
throw Error('Must use MyTabPanel component in a MyTabs component');
}
return element;
}
private handleChange(event: React.ChangeEvent<{}>, newValue: number): void {}
private renderAppBarTab(child, index: number): JSX.Element {
const label = 'Test';
const element = (
<Tab label={label} key={index} />
);
return element;
}
set value(value:number) {
this.setState({value: value});
}
}
ReactDOM.render(
<React.StrictMode>
<MyTabs>
<MyTabPanel label='Tab1'>
<Typography>Test1</Typography>
</MyTabPanel>
<MyTabPanel label='Tab2'>
<Typography>Test2</Typography>
</MyTabPanel>
</MyTabs>
</React.StrictMode>
, document.getElementById('root'));
Я не знаю, почему я могу ' не заставить его работать на CodePen , когда моя рабочая станция работает нормально.
Мой родительский компонент MyTabset мой дочерний компонент MyTabPanel .
Мне понадобится ваша помощь по следующим пунктам:
- В моем родительском компоненте, renderAppBarTab метод, я хочу получить свойства моего дочернего компонента, в частности, свойство метки (сегодня я установил жесткую константу, потому что не знаю, что делать)? TypeScript не позволяет мне вызывать props для моих детей, потому что тип моего дочернего параметра ему не подходит. Я хотел бы получить свойства типа, используемого для моего дочернего компонента (MyTabPanelProperties).
- Я хотел бы обновить скрытое свойство моего дочернего компонента, изменив статус моего родительского компонента (свойство значения) , как в примере, предложенном material-ui.
У кого-нибудь есть идеи?
Заранее спасибо