То, чего я пытаюсь добиться, это иметь BaseComponent, который будет повторно использоваться в другом ParentComponent.
Мой реквизит компонента базовой карты ->
export type MSGameCardProps = {
title: string;
fetchGamesFn : (searchText: string) => Promise<IResultObject<any,any>>;
};
Мой рендеринг базовой карты все необходимые основы c логика и управление (входы, автозаполнение, заголовок). Например, он обеспечивает автозаполнение с простой функцией отладки поиска.
У родительского компонента Me нет необходимости иметь реквизит, и он будет использовать базовую карту следующим образом:
export type MSGameSrcCardProps = {};
export const MSGameSrcCard: React.FC<MSGameSrcCardProps> = () => {
const gameSvc = useGameService();
const fetchGame = async (searchText: string) => {
const rs = await result(gameSvc.getAll(searchText));
return rs;
};
return (
<MSGameCard title={"Convert From"} fetchGamesFn={fetchGame}></MSGameCard>
);
};
export default MSGameSrcCard;
Родительский компонент предоставит функцию fetchGames, которая может отличаться. Он также установит заголовок и может позже установить некоторые другие флаги.
Этот шаблон приводит к этой ошибке: Type '{}' is missing the following properties from type 'MSGameCardProps': title, fetchGamesFn
при попытке использовать родительский компонент на моей странице следующим образом: <MSGameSrcCard></MSGameSrcCard>
Я не понимаю, почему мой родитель должен иметь эти свойства, поскольку они требуются только в дочернем компоненте и полностью заполнены в функции моего родительского компонента.
Я не хочу делать их необязательными (? ) поскольку они действительно необходимы; конечно, только для моего базового компонента
Я пытался экспортировать свой базовый компонент КАК ЛЮБОЙ , который устраняет ошибку, но теперь мой props.fetchGamesFn всегда неопределен, даже передавая его внутри моей функции родительского компонента.
Может быть, я делаю это неправильно, но есть ли способ иметь родительские компоненты без реквизита с дочерним элементом, который требует реквизиты?
РЕДАКТИРОВАТЬ: Вот мое определение базового компонента MSGameCard
export const MSGameCard: React.FC<MSGameCardProps> = props => {
const [games, setGames] = React.useState([
{
name: ""
}
]);
const [selectedGame, setSelectedGame] = React.useState<any>();
const [previousGame, setPreviousGame] = React.useState<any>();
const [isLoading, setIsLoading] = React.useState(false);
const [opacity, setOpacity] = React.useState(0);
const fetchGameBase = (searchText: string) => {
setIsLoading(true);
console.log(props.fetchGamesFn);
props.fetchGamesFn(searchText).then(rs =>{
if (rs.isSuccess) setGames(rs.result.data);
setIsLoading(false);
})
};
const searchDebounce = debounce(300, fetchGameBase);
React.useEffect(() => {
fetchGameBase("");
}, []);
const onGameChanged = (event: any, value: any) => {
if (selectedGame) setPreviousGame(selectedGame);
setOpacity(0);
if (value) {
setTimeout(() => {
setSelectedGame(value);
setOpacity(0.2);
}, 300);
}
};
const onInputChanged = (e: any) => {
let value = e.target.value;
if (!value) value = "";
searchDebounce(value);
};
const getSelectedGameImg = () => {
const bgUrl: string = selectedGame
? selectedGame.bg_url
: previousGame?.bg_url;
return bgUrl;
};
return (
<Card style={{ position: "relative", zIndex: 1 }} variant="outlined">
<CardContent style={{ zIndex: 1 }}>
<Typography variant="h5" gutterBottom>
{props.title}
</Typography>
<Grid container spacing={3}>
<Grid item xs={12} sm={6}>
<Autocomplete
options={games}
getOptionLabel={option => option.name}
onChange={onGameChanged}
onInputChange={onInputChanged}
renderInput={params => (
<TextField
{...params}
label="Source game"
fullWidth
InputProps={{
...params.InputProps,
endAdornment: (
<React.Fragment>
{isLoading ? (
<CircularProgress color="primary" size={30} />
) : null}
{params.InputProps.endAdornment}
</React.Fragment>
)
}}
/>
)}
/>
</Grid>
</Grid>
<Grid container direction="row" spacing={3}>
<Grid item xs={12} sm={6}>
<TextField label="DPI" fullWidth />
</Grid>
<Grid item xs={12} sm={6}>
<TextField label="Sensitivity" fullWidth />
</Grid>
</Grid>
</CardContent>
<img
style={{ opacity: opacity }}
className="gameImage"
src={getSelectedGameImg()}
/>
</Card>
);
};
export default MSGameCard;