kirillzyusko / react-native-keyboard-controller

Keyboard manager which works in identical way on both iOS and Android
https://kirillzyusko.github.io/react-native-keyboard-controller/
MIT License
1.62k stars 67 forks source link

Unexplained scrolling and flickering on Huawei devices #476

Closed nangongmoyan closed 3 months ago

nangongmoyan commented 3 months ago

Describe the bug In the Huawei device where I recorded the screen, I can see that when the input box is being input or deleted, the content on the screen keeps moving upwards, and the input box will flash continuously when continuing to input or delete when it exceeds the screen.

Code snippet I made the following changes directly on the AwareScrollView in your example, adding the value and onChangeText of the TextInput

import React, { useState } from "react";
import { KeyboardAwareScrollView } from "react-native-keyboard-controller";

import TextInput from "../../../components/TextInput";

import { styles } from "./styles";

import type { ExamplesStackParamList } from "../../../navigation/ExamplesStack";
import type { StackScreenProps } from "@react-navigation/stack";

type Props = StackScreenProps<ExamplesStackParamList>;

export default function AwareScrollView({ navigation }: Props) {

  const [content1, setContent1] = useState('')
  const [content2, setContent2] = useState('')
  const [content3, setContent3] = useState('')
  const [content4, setContent4] = useState('')
  const [content5, setContent5] = useState('')
  const [content6, setContent6] = useState('')
  const [content7, setContent7] = useState('')
  const [content8, setContent8] = useState('')
  const [content9, setContent9] = useState('')
  const [content10, setContent10] = useState('')

  return (
    <>
      <KeyboardAwareScrollView
        testID="aware_scroll_view_container"
        bottomOffset={50}
        enabled
        style={styles.container}
        contentContainerStyle={styles.content}
      >
          <TextInput
            value={content1}
            onChangeText={setContent1}
            placeholder={`TextInput#1`}
          />
          <TextInput
            value={content2}
            onChangeText={setContent2}
            placeholder={`TextInput#2`}
          />
          <TextInput
            value={content3}
            onChangeText={setContent3}
            placeholder={`TextInput#3`}
          />
          <TextInput
            value={content4}
            onChangeText={setContent4}
            placeholder={`TextInput#4`}
          />
          <TextInput
            value={content5}
            onChangeText={setContent5}
            placeholder={`TextInput#5`}
          />
          <TextInput
            value={content6}
            onChangeText={setContent6}
            placeholder={`TextInput#6`}
          />
          <TextInput
            value={content7}
            onChangeText={setContent7}
            placeholder={`TextInput#7`}
          />
          <TextInput
            value={content8}
            onChangeText={setContent8}
            placeholder={`TextInput#8`}
          />
          <TextInput
            value={content9}
            onChangeText={setContent9}
            placeholder={`TextInput#9`}
          />
          <TextInput
            value={content10}
            onChangeText={setContent10}
            placeholder={`TextInput#10`}
          />
      </KeyboardAwareScrollView>
    </>
  );
}

To Reproduce Steps to reproduce the behavior:

It seems that the two input boxes at the top do not have this problem. The triggering point of this problem is that there are too many input boxes on the page, which exceeds the height of the machine. You can try the code I posted and debug it on the corresponding model.

Expected behavior I want the keyboard to push the input box up normally, but not move or flicker when I enter or delete.

Screen Recording The following screen recording shows the effect on a real device after I adjusted the code in your example. I didn't make too many adjustments, just added value and onChangeText. I guess it was onChangeText that caused the internal processing problem in your library.

https://github.com/kirillzyusko/react-native-keyboard-controller/assets/48037565/de3c9b79-8b60-48cf-8b35-87f073e7c8de

Smartphone (please complete the following information): Screenshot_20240619_151211_com android settings

Additional context At present, I have only reproduced this problem on this model. The same code does not appear on Xiaomi, Samsung and other devices.

kirillzyusko commented 3 months ago

@nangongmoyan aha, very interesting!

Do you have any ideas on how to reproduce this problem without real Huawei/HarmonyOS? Maybe Huawei gives an access to their own device farm?

Can you try to comment out this code https://github.com/kirillzyusko/react-native-keyboard-controller/blob/02c842d9f9f2d67607a97ac6183753e6db0760a0/src/components/KeyboardAwareScrollView/index.tsx#L198-L211 and see if the issue is reproducible again?

nangongmoyan commented 3 months ago

@nangongmoyan aha, very interesting!  啊哈,很有趣!

Do you have any ideas on how to reproduce this problem without real Huawei/HarmonyOS? Maybe Huawei gives an access to their own device farm?您对如何在没有真正的华为/HarmonyOS 的情况下重现此问题有什么想法吗?也许华为允许访问他们自己的设备群?

Can you try to comment out this code 你可以尝试注释掉这段代码吗

https://github.com/kirillzyusko/react-native-keyboard-controller/blob/02c842d9f9f2d67607a97ac6183753e6db0760a0/src/components/KeyboardAwareScrollView/index.tsx#L198-L211

and see if the issue is reproducible again? 看看问题是否可以再次重现?

I tried to comment out the code as you suggested, but unfortunately the problem still occurred when running it

kirillzyusko commented 3 months ago

I tried to comment out the code as you suggested, but unfortunately the problem still occurred when running it

Okay, my another suggestion then is that we are calling maybeScroll function somewhere else. I think there are 3 main places:

If you are saying, that the code above doesn't work and bug is still there, then I can suggest to comment out maybeScroll usages and see which one of two remaining actually causes problems. May I ask you to debug that?

kirillzyusko commented 3 months ago

After digging into the code more, I think I found the reason why it happens. When you update a state, then you trigger a re-render. Triggering a re-render will create a new object/handler for useSmoothKeyboardHandler. In https://github.com/kirillzyusko/react-native-keyboard-controller/blob/817127f70fee265760261f7046ce3e8b9d9ddbb7/src/components/KeyboardAwareScrollView/useSmoothKeyboardHandler.ts#L71 we depend on handler (which will be re-created). As a result we'll dispatch two events onMove and onEnd. And onMove handler will call maybeScroll and we'll scroll into a wrong position.

Can you try to use deps instead of [handler] and see whether the issue is reproducible again or not?

nangongmoyan commented 3 months ago

maybeScroll

onMove:When only the maybeScroll method in onMove is commented out, the input box will shift upwards when input is first made, and will not shift again afterwards, but the input box below will not be pushed up by the keyboard.The screen recording is as follows: https://github.com/kirillzyusko/react-native-keyboard-controller/assets/48037565/03c6c6c0-9c72-4969-bf57-d2ef98143772

useAnimatedReaction: When only the maybeScroll method in useAnimatedReaction is commented, the input box will always shift upwards, and the input box below can also be lifted up normally, but it also always shifts upwards.The screen recording is as follows: https://github.com/kirillzyusko/react-native-keyboard-controller/assets/48037565/cc954d61-9ea1-41bc-bd88-9522f1cb1c12

useFocusedInputHandler: When only the maybeScroll method in useFocusedInputHandler is commented, the input box will always shift upwards, and the input box below can also be lifted normally, but it also always shifts upwards.The screen recording is as follows: https://github.com/kirillzyusko/react-native-keyboard-controller/assets/48037565/b7529cae-6123-4295-a321-2c0e591d645a

kirillzyusko commented 3 months ago

@nangongmoyan cool, that means that the problem is definitely in onMove handler. I think https://github.com/kirillzyusko/react-native-keyboard-controller/issues/476#issuecomment-2178048371 should fix the problem, but if it's not, then I'll give next steps for further debugging 👀

nangongmoyan commented 3 months ago

@nangongmoyan cool, that means that the problem is definitely in onMove handler. I think #476 (comment) should fix the problem, but if it's not, then I'll give next steps for further debugging 👀酷,这意味着问题肯定出在 onMove 处理程序中。我认为 #476 (comment) 应该解决问题,但如果没有,那么我将给出进一步调试的后续步骤 👀

I tried it and it worked, but after switching to deps, this area turned red. It seems that it is not recommended for me to use it this way. typescript tips: Argument of type 'DependencyList | undefined' is not assignable to parameter of type 'DependencyList'. Type 'React.DependencyList' is not assignable to type 'import("/Users/nangongmoyan/Code/company/react-native-keyboard-controller/example/node_modules/react-native-reanimated/lib/typescript/reanimated2/hook/commonTypes").DependencyList'.

image

kirillzyusko commented 3 months ago

@nangongmoyan yes, because of types mismatches between REA and react 👀

I fixed it in my PR - I'll merge it today, but I can not say when I'll prepare a new release (hopefully on this week, but can not promise).

In a meantime you can patch it using patch-package 👍