APSL / react-native-keyboard-aware-scroll-view

A ScrollView component that handles keyboard appearance and automatically scrolls to focused TextInput.
MIT License
5.24k stars 643 forks source link

Example in a functional component #550

Open egor-sorokin opened 1 year ago

egor-sorokin commented 1 year ago

"react-native-keyboard-aware-scroll-view": "^0.9.5", "react-native": "0.64.2", "@types/react": "^17.0.38", "typescript": "^4.5.4"

I am trying to use the library with functional components. I have the following screen (parent component)

const MyScreen = () => {
   const formRef = useRef<typeof FormContainer | null>(null);

   const handleTextFieldPress = () => {
    if (formRef && formRef.current) {
      formRef.current!.scrollToEnd({ animated: true });
    }
  };

   <FormContainer
        style={styles.formContainer}
        scrolling
        ref={formRef}
      >
      ...
      <View>
         <TextField onPress={handleTextFieldPress} />
      </ View>
      </ FormContainer>
}

then I have a FormContainer, where the library is used:

const FormContainer = forwardRef((props: Props) => {
  const scroll = useRef();

  const scrollToEnd = (options?: { animated: boolean }) => {
    if (!isNil(scroll)) {
      scroll!.props.scrollToEnd(options);
    }
  };

   return (
      <KeyboardAwareScrollView
        style={[styles.scrollView, scrollViewStyle]}
        keyboardShouldPersistTaps="handled"
        innerRef={ref => {
            scroll.current = ref;
        }}
        enableResetScrollToCoords={false}
        extraScrollHeight={34}
        onScroll={updateScroll}
      >
        {renderContent()}
      </KeyboardAwareScrollView>
    );
}

with this minimal setup, I am getting the following errors: for scroll.current = ref - Type 'Element' is not assignable to type 'undefined'. for scroll!.props.scrollToEnd(options); - Property 'props' does not exist on type 'MutableRefObject '. for formRef.current!.scrollToEnd({ animated: true }); - Property 'scrollToEnd' does not exist on type 'ForwardRefExoticComponent >'.

Is there any way to implement this behavior with functional components? I feel forwardRef is needed since ref is used inside, once I remove it I get an error in the parent component on line ref={formRef}: " Property 'ref' does not exist on type 'IntrinsicAttributes & Props'."

tonibardina commented 1 year ago

Hello @egor-sorokin , I will try to help you with some of your doubts :)

scroll.current = ref : You can tell which kind of ref the element will hold, in my case there are no errors if doing so -> const scroll = useRef<JSX.Element>();

scroll!.props.scrollToEnd(options); : I have come across the same issue, looks like there is no props property at least when using functional components. As an alternative you can do: scroll.current.scrollTo

Haven't had time to go further into the other issues hope this helps for now