4

I'm trying to make a component that will show a loading circle when the prop isLoading is true, and otherwise show the child component. I'd like to use the component in other components likes this...

import Loading from './Loading.tsx'

...

const [isLoading,setLoading] = React.useState(false);

return (
<Loading isLoading={isLoading}>
     <div>this component will show when loading turns to true</div>
</Loading> );

I'm getting the typscript error

Type '({ isLoading, color, children, }: PropsWithChildren<LoadingProps>) => Element | { children: ReactNode; }' is not assignable to type 'FunctionComponent<LoadingProps>'.

Type 'Element | { children: ReactNode; }' is not assignable to type 'ReactElement<any, any> | null'.
    Type '{ children: ReactNode; }' is missing the following properties from type 'ReactElement<any, any>': type, props, key  TS2322

Can someone point out what I'm doing wrong?


    import React, { FunctionComponent } from 'react';
    import { CircularProgress } from '@material-ui/core';

    type LoadingProps = {
        isLoading: boolean;
        color: 'primary' | 'secondary' | 'inherit' | undefined;
    };

    const Loading: FunctionComponent<LoadingProps> = (props) => {
    
        if(props.isLoading){
            return <CircularProgress color={props.color || 'primary'} />
        }
    
        return props.children;
    };

    export default Loading;
yoges nsamy
  • 1,275
  • 1
  • 16
  • 29
M. Stolte
  • 105
  • 1
  • 1
  • 11

3 Answers3

4

It is recommended (see here) to explicitly define the type of your children when using React.FunctionComponents as your function type.

So

type LoadingProps = {
    isLoading: boolean
    color: 'primary' | 'secondary' | 'inherit' | undefined
    children: React.ReactNode
}

This will also ensure correct typing on the return.

sam256
  • 1,291
  • 5
  • 29
4

That´s because of return props.children.

You should wrapper it with a fragment, like this:

const Loading: React.FC<LoadingProps> = (props) => {
return props.isLoading ? (
    <CircularProgress color={props.color || "primary"} />
  ) : (
    <>{props.children}</>
  );
};
Luis Paulo Pinto
  • 5,578
  • 4
  • 21
  • 35
-1

The link of @sam256 is right but it says that there is a new syntax via React.FunctionComponent where children are implicit.

New syntax:

const Title: React.FunctionComponent<{ title: string }> = ({
  children,
  title,
}) => <div title={title}>{children}</div>;

Should work like this:

<Title title="my string">
    <div>Implicit child</div>
</Title>
CodingYourLife
  • 7,172
  • 5
  • 55
  • 69