Возникла проблема при использовании композиции с родительским и базовым компонентом дляact.js / typescript - PullRequest
0 голосов
/ 10 марта 2020

То, чего я пытаюсь добиться, это иметь 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;

1 Ответ

1 голос
/ 10 марта 2020

Постоянно обновлять уведомление


После проверки предоставленной вами minimum reproducible example.

Я не нашел ошибку типа, я что-то упустил?

Поскольку ошибка возникла в обоих случаях, я бы оставил только строку для проверки

import * as React from "react";
import "./styles.css";

export type MSGameCardProps = {
  title: string;
};
export type MSGameSrcCardProps = {};

export const MSGameSrcCard: React.SFC<MSGameSrcCardProps> = () => {
  return <MSGameCard title={"Convert From"} />;
};

const MSGameCard: React.SFC<MSGameCardProps> = (props: MSGameCardProps) => {
  console.log(props); // Object {title: "Convert From"}
  return <></>;
};

export default function App() {
  return (
    <div className="App">
      <MSGameSrcCard />
    </div>
  );
}

Попробуйте ее здесь:

Edit vigorous-resonance-zw2ko

...