Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Typescript React Functional Component with props.children

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;
like image 217
M. Stolte Avatar asked Oct 20 '25 13:10

M. Stolte


2 Answers

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.

like image 78
sam256 Avatar answered Oct 23 '25 04:10

sam256


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}</>
  );
};
like image 45
Luis Paulo Pinto Avatar answered Oct 23 '25 02:10

Luis Paulo Pinto