A.Vincent
A.Vincent

Reputation: 267

how use props.children with ts

I am new in typescript and I try to use correctly props.children with typescript but i get an error.

interface IFetcher {
  url: string;
}

const Fetcher: React.FC<IFetcher> = props => {
  const [data, setData] = useState<Array<{}>>();
  const [isLoading, setLoading] = useState<boolean>(false);
  const [error, setError] = useState<string>("");

  useEffect(() => {...})

  return props.children(data, error, isLoading);
};

this is the erreur on props.children : Cannot invoke an object which is possibly 'null' or 'undefined'.

i use this trick for resolv it :

interface IFetcher {
  url: string;
}

const Fetcher: React.FC<IFetcher> = props => {
  const [data, setData] = useState<Array<{}>>();
  const [isLoading, setLoading] = useState<boolean>(false);
  const [error, setError] = useState<string>("");

  useEffect(() => {...})

  return props.children && props.children(data, error, isLoading);
};

but i have another erreur :

this expression is not callable. No constituent of type 'string | number | true | {} | ReactElement ReactElement Component)> | null) | (new (props: any) => Component)> | ReactNodeArray | ReactPortal' is callable.

I need help for use the good way plz.

EDIT I found this solution :

interface IFetcher {
  url: string;
  children(data: Array<{}>, error: string, isLoading: boolean): ReactElement;
}

const Fetcher: React.FC<IFetcher> = props => {
  const [data, setData] = useState<Array<{}>>([]);
  const [isLoading, setLoading] = useState<boolean>(false);
  const [error, setError] = useState<string>("");

  useEffect(() => {...});

  return props.children(data, error, isLoading);
};

When i define children i have no erreur now but is this the right solution ?

Upvotes: 11

Views: 9600

Answers (1)

Shubham Khatri
Shubham Khatri

Reputation: 281686

When you trying to call children props as a function you must be sure that children exists. In order for you to impose a typecheck on children, you need to provide it in interface

interface IFetcher {
  url: string;
  children(data: Array<{}>, error: string, isLoading: boolean): ReactElement;
}

const Fetcher: React.FC<IFetcher> = props => {
  const [data, setData] = useState<Array<{}>>([]);
  const [isLoading, setLoading] = useState<boolean>(false);
  const [error, setError] = useState<string>("");

  useEffect(() => {...});

  return props.children(data, error, isLoading);
};

Upvotes: 15

Related Questions