Home > OS >  Cannot invoke an object which is possibly 'undefined' in children component
Cannot invoke an object which is possibly 'undefined' in children component

Time:10-16

In my expo typescript app, I have a function in a root component:

  const getCardType = (type = ECardType.WOOD) => {
    setCardType(type);
  };

and pass it in my first child component:

  <Slider data={slideData} autoPlay={false} getCardType={getCardType} />

Here is my first child component where I pass the function, and it types declaration:

  readonly getCardType?: (type: ECardType) => void;



  const Slider: React.FunctionComponent<ISliderProps> = ({
    data,
    autoPlay,
    getCardType,
 })

After that I pass it into a second child component:

<SliderCardItem cardItem={item} index={index} getCardType={getCardType} />

And in this SliderItem component, I use this function:

  useEffect(() => {
    getCardType(cardType);
  }, [cardType]);

But Have a TS error: Cannot invoke an object which is possibly 'undefined' in children component

I set the cardType below in an onPress()
I have this error only in this component
An idea to fix this error?

CodePudding user response:

Remove the ? in the type declaration, if it's required. If it's not required, you have to check if it exists first.

Another point, getCardType is actually a dependency of that effect as well, but by looking at it it's safe, to ignore it (because it just wraps a setState) call.

I don't like ignoring stuff, though. So if I were you, I'd probably write it like this:

  // useCallback makes getCardType referentially identical between renders
  const getCardType = useCallback((type = ECardType.WOOD) => {
    setCardType(type);

  // safe to ignore setCardType in the dependencies because it's a dispatcher
  },[]);

// ... and in the child:

  useEffect(() => {
    getCardType(cardType);
  }, [ getCardType, cardType ]);

I'm honestly dying to know what that useEffect is about in the child, because it smells a little fishy.

CodePudding user response:

getCardType might be undefined, as stated in your type here:

getCardType?: (type: ECardType) => void;

Then you're trying to call it without checking if it exists:

useEffect(() => {
  getCardType(cardType);
}, [cardType]);

So you'll need to perform that check:

useEffect(() => {
  if (getCardType) getCardType(cardType);
}, [cardType]);

or with optional chaining:

useEffect(() => {
  getCardType?.(cardType);
}, [cardType]);

If it will always be present then you can make it non optional in your type:

getCardType: (type: ECardType) => void;

  • Related