Search code examples
reactjstypescriptnext.jsreact-typescript

Props will be passed to children but Typescript throws an error


I have a component that will be rendering a child based on the specific "league" a user is viewing. In the MLB case, for example, typescript is throwing an error because I am not passing the correct props to the child. However, the parent that I am rendering it from will have the props and create a clone of that component to pass as the end result. Is there a better way for me to do what I am trying to do, or is there a (correct) way to make typescript stop yelling at me for this?

Edit: I think I can just pass dummy props, but still would like to know if this is the best way to go about doing what I am trying to do.

export interface MlbScore {
  data: GameStatsSchemaBaseProps;
  marker: string;
  period: number;
}

export const MlbScore = ({ data, marker, period }: MlbScore) => {
// return component
};

export const Scoreboard = ({ league, data, children }: ScoreboardPropTypes) => {
  const { period, status, marker, buttonText, incrementGame } =
    useMoveGame(league);

  const handleClick = () => {
    ...
  };

 ...

  const childrenWithProps = React.Children.map(children, (child) => {
    if (React.isValidElement(child)) {
      const newProps = { data, period, marker };
      return React.cloneElement(child, newProps);
    }
  });

  return (
    <div id="scoreboard">
      ...
      {childrenWithProps}
      ...
    </div>
  );
};

export const MlbGame = async () => {
  const data = await callApi("/game/mlb");

  return (
    <Container id="scoreboard">
      <Scoreboard league="MLB" data={data}>
        <MlbScore /> // this is where it is throwing the error for props not being passed
      </Scoreboard>
    </Container>
  );
};

Solution

  • I think you are trying to pass in the MlbScore-component to the Scoreboard via its children. A better way would be to pass it in as a prop, and then use the component type to map over the data array and draw the MlbScore components:

    <Scoreboard league="MLB" data={data} scoreComponent={MlbScore}>
    

    And then in scoreboard, you update the props, and simply use the passed in component function to create the children.

    Alternatively, why are you not just passing the data directly to the MlbScore component?

    <MlbScore data={data} />
    

    P.S. If you just want the error to go away, you can probably make the props optional on MlbScore, by adding a ?, like marker?: string