Невозможно вызвать объект, который, возможно, «не определен» в дочернем компоненте

#javascript #typescript #react-native #undefined

Вопрос:

В моем приложении expo typescript у меня есть функция в корневом компоненте:

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

и передайте это в моем первом дочернем компоненте:

 lt;Slider data={slideData} autoPlay={false} getCardType={getCardType} /gt;  

Вот мой первый дочерний компонент, в котором я передаю функцию, и она вводит объявление:

 readonly getCardType?: (type: ECardType) =gt; void;     const Slider: React.FunctionComponentlt;ISliderPropsgt; = ({  data,  autoPlay,  getCardType,  })  

После этого я передаю его во второй дочерний компонент:

 lt;SliderCardItem cardItem={item} index={index} getCardType={getCardType} /gt;  

И в этом компоненте SliderItem я использую эту функцию:

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

Но есть ошибка TS: Не удается вызвать объект, который, возможно, «не определен» в дочернем компоненте

Я установил тип карты ниже в onPress()
У меня эта ошибка только в этом компоненте
Есть идея исправить эту ошибку?

Комментарии:

1. В качестве отступления… Вызываемая функция getCardType , которая внутренне вызывает вызываемую функцию setCardType , звучит так, как будто вы настраиваете себя на возможные ошибки позже. На самом деле это не получение значения, а установка значения.

Ответ №1:

getCardType может быть неопределенным, как указано в вашем типе здесь:

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

Тогда вы пытаетесь вызвать его, не проверяя, существует ли он:

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

Поэтому вам нужно будет выполнить эту проверку:

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

или с дополнительной цепочкой:

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

Если он всегда будет присутствовать, вы можете сделать его необязательным в своем типе:

getCardType: (type: ECardType) =gt; void;

Комментарии:

1. Thx, проверив, существует ли он с дополнительной цепочкой, он работает 😉

Ответ №2:

Удалите ? объявление типа, если это необходимо. Если это не требуется, сначала вы должны проверить, существует ли оно.

Другой момент, getCardType на самом деле, также зависит от этого эффекта, но, глядя на него, можно с уверенностью игнорировать его (потому что он просто обертывает вызов setState).

Хотя мне не нравится игнорировать вещи. Так что на твоем месте я бы, наверное, написал это так:

 // useCallback makes getCardType referentially identical between renders  const getCardType = useCallback((type = ECardType.WOOD) =gt; {  setCardType(type);   // safe to ignore setCardType in the dependencies because it's a dispatcher  },[]);  // ... and in the child:   useEffect(() =gt; {  getCardType(cardType);  }, [ getCardType, cardType ]);  

Честно говоря, мне до смерти хочется узнать, что это useEffect такое в ребенке, потому что от него немного пахнет рыбой.