Ошибка TypeScript forwardRef в React Native

У меня есть онбординг и слайд-компоненты. Я передаю ref как опору для сдвига компонента из адаптивного компонента с помощью forwardRef. Он работает нормально, но машинописный текст выдает ошибку

Мои компоненты, как показано ниже

const Onboarding = () => {
  const { width } = useOrientation();
  const scrollX = new Animated.Value(0);
  const scroll = useRef<Animated.ScrollView>(null);
  const onScroll = (event: any) => {
    Animated.event([{ nativeEvent: { contentOffset: { x: scrollX } } }]);
  };

  return (
    <Box flex={1}>
      <Animated.ScrollView
        ref={scroll}
        scrollEventThrottle={16}
        onScroll={onScroll}
        horizontal
      >
        {slides.map((data, index) => (
          <Slide key={index} data={data} ref={scroll} {...{ index, scrollX }} />
        ))}
      </Animated.ScrollView>
    </Box>
  );
};

interface SlideProps {
  data: {
    label: string;
    description: string;
    src: string;
  };
  scrollX: Animated.Value<0>;
  index: number;
}

export const Slide = forwardRef<Animated.ScrollView, SlideProps>(
  ({ data, scrollX, index }: SlideProps, ref) => {
    const { width, height } = Dimensions.get("window");

    const aspect = height / width;

    return (
      <Box flex={1} width={width} backgroundColor="mainBackground">
        <TouchableOpacity
          onPress={() =>
              //error here
            ref?.current?.getNode().scrollTo({ x: width * (index + 1), y: 0 })
          }
        >
          <Text>heyy</Text>
        </TouchableOpacity>
      </Box>
    );
  }
);

Ошибка такая: Свойство 'current' не существует для типа '((instance: ScrollView | null) = ›void) | MutableRefObject ‹ScrollView | нулевой>'. Как я могу исправить эту проблему? Спасибо.


person Oğulcan Karayel    schedule 09.09.2020    source источник


Ответы (1)


Честно говоря, странно видеть forwardRef в этом контексте. Я имею в виду, что вы действительно хотите, чтобы ссылка ссылалась на Animated.ScrollView, а не на объект Slide.

Вариант 1 (на мой взгляд, уродливый): передать ref как свойство Slide (а не как сам ref).

Вариант 2 (который я предпочитаю): заставить Slide сообщить Onboarding о том, что событие для прессы произошло, и сделать так, чтобы Onboarding scrollTo

const Onboarding = () => {
  const { width } = useOrientation();
  const scrollX = new Animated.Value(0);
  const scroll = useRef<Animated.ScrollView>(null);
  const onScroll = (event: any) => {
    Animated.event([{ nativeEvent: { contentOffset: { x: scrollX } } }]);
  };
  const onPress = (width: number, index: number) => {
    scroll.current?.getNode().scrollTo({ x: width * (index + 1), y: 0 })
  }

  return (
    <Box flex={1}>
      <Animated.ScrollView
        ref={scroll}
        scrollEventThrottle={16}
        onScroll={onScroll}
        horizontal
      >
        {slides.map((data, index) => (
          <Slide key={index} onPress={onPress} data={data} {...{ index, scrollX }} />
        ))}
      </Animated.ScrollView>
    </Box>
  );
};

interface SlideProps {
  // same as before
  onPress: (width:number, index:number) => void
}

export const Slide = ({ data, scrollX, index, onPress }: SlideProps) => {
    const { width, height } = Dimensions.get("window");

    const aspect = height / width;

    return (
      <Box flex={1} width={width} backgroundColor="mainBackground">
        <TouchableOpacity
          onPress={() => onPress(width, index)}
        >
          <Text>heyy</Text>
        </TouchableOpacity>
      </Box>
    );
  }
);
person Guilhermevrs    schedule 09.09.2020
comment
Спасибо за ответ. Почему forwardRef странный? Вы можете объяснить ? Я хочу понять это - person Oğulcan Karayel; 09.09.2020
comment
Да, конечно! ForwardRef, как показано здесь: reactjs.org/docs/forwarding-refs.html, это когда вы хотите переслать ссылку, созданную родителем, одному дочернему элементу. Вы пытаетесь разделить рефери между двумя детьми. Если вы видите в своем примере, вы создаете ссылку прокрутки во встроенном компоненте и пересылаете ее в Animated.ScrollView. - person Guilhermevrs; 09.09.2020
comment
Спасибо за вашу помощь, это очень помогло мне понять - person Oğulcan Karayel; 09.09.2020