javascript - Cum pot să trec Componenta A cu proprietăți generice în componenta B ca o proprietate opțională
Scriu un component personalizat select (SelectBase) cu o funcție de a înlocui componentele de bază create în interiorul componentului de bază. De exemplu, dacă nu transmit un ModalComponent în interiorul SelectBase, voi folosi BaseModalComponent.
Problema este că proprietățile prop-ului ModalComponent sunt necunoscute și vreau să fac posibilă trecerea proprietăților ModalComponent în interiorul SelectBase atunci când folosesc SelectBase cu ModalComponent personalizat.
const SomeSelectInstance = SelectBase<ISomeSelectInstanceProps>;
M-am oprit la următoarea interfață a SelectBase:
import { ComponentType } from 'react';
import { Drawer } from '@mui/material';
interface ISelectBaseProps<ModalProps> {
open: boolean;
modalRenderMode: 'desktop' | 'mobile'
ModalComponent?: ComponentType<ModalProps>;
ModalComponentProps?: ModalProps;
În interiorul SelectBase trebuie să folosesc Drawer sau un BaseMenuList personalizat în funcție de valoarea modalRenderMode:
const BaseModalComponent = modalRenderMode === 'desktop' ? BaseMenuList : Drawer;
const Modal = ModalComponent ?? BaseModalComponent;
const modalElement = <Modal {...ModalComponentProps}>{children}</Modal>; // here I get Error
Eroarea pe care o primesc: „Tipul „{ children: ReactNode; }” nu poate fi atribuit tipului „ModalProps”
Cod complet SelectBase:
import { ComponentType, ReactNode, useRef, useState } from 'react';
import { Drawer, PopoverProps, SelectProps } from '@mui/material';
import { IconSelectArrow } from 'icons';
import { BaseMenuList } from 'portfolio3/ui-kit';
import { BaseMenuItem } from 'portfolio3/ui-kit/menu';
import { IInputBaseProps, StyledSelectBase } from 'portfolio3/ui-kit/selects/bases';
import { InputRenderMode } from 'portfolio3/ui-kit/types';
export interface ISelectBaseProps extends SelectProps {
inputRenderMode: InputRenderMode; // переименовать в inputRenderMode
}
interface ISelectBasePropss<ModalProps> {
inputRenderMode: InputRenderMode;
modalRenderMode: 'desktop' | 'mobile';
open: boolean;
onClick: () => void;
onClose: PopoverProps['onClose'];
type?: 'select' | 'input';
ModalComponent?: ComponentType<ModalProps>;
InputComponent?: ComponentType<IInputBaseProps>;
ModalComponentProps?: ModalProps;
InputComponentProps?: IInputBaseProps;
children: ReactNode;
}
// eslint-disable-next-line prettier/prettier
const SelectBase = <ModalProps, >({
inputRenderMode,
modalRenderMode,
open,
onClick,
onClose,
InputComponent,
ModalComponent,
ModalComponentProps,
InputComponentProps,
children,
type = 'select',
}: ISelectBasePropss<ModalProps>) => {
const selectRef = useRef<HTMLDivElement>(null);
const inputProps: IInputBaseProps = {
...InputComponentProps,
rendermode: inputRenderMode,
ref: selectRef,
onClick,
readOnly: type === 'select',
inputProps: {
style: {
cursor: type === 'select' ? 'pointer' : 'initial',
},
},
};
const modalProps: ModalProps = {
...ModalComponentProps,
open,
anchorEl: selectRef.current,
onClose,
};
const inputElement = InputComponent ? <InputComponent {...inputProps} /> : <StyledSelectBase {...inputProps} />;
const BaseModalComponent = modalRenderMode === 'desktop' ? BaseMenuList : Drawer;
const Modal = ModalComponent ?? BaseModalComponent;
const modalElement = <Modal {...modalProps}>{children}</Modal>;
return (
<div className="select-base">
{inputElement}
{modalElement}
</div>
);
};
export default SelectBase;<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>Cum pot rezolva asta sau poate există o variantă mai bună sau mai optimizată?