react-native-bottom-sheet icon indicating copy to clipboard operation
react-native-bottom-sheet copied to clipboard

[Bug]: Android+iOS TextInput Keyboard lagging BottomSheetModal - Reanimated error

Open MarzyCoder opened this issue 11 months ago โ€ข 45 comments

Version

v5

Reanimated Version

v3

Gesture Handler Version

v2

Platforms

Android

What happened?

Keyboard is lagging - Meanwhile this is logging in the console:

Reanimated] Reading from `value` during component render. Please ensure that you do not access the `value` property or use `get` method of a shared value while React is rendering a component.

If you don't want to see this message, you can disable the `strict` mode. Refer to:
https://docs.swmansion.com/react-native-reanimated/docs/debugging/logger-configuration for more details.

Code: const [text, setText] = useState("")

      <BottomSheetModal ref={bottomSheetModalRef} index={1} snapPoints={snapPoints} enablePanDownToClose enableDismissOnClose >
        <BottomSheetView>

          <BottomSheetTextInput
            placeholder='Text...'
            value={text}
            onChangeText={setText} 
          />
                
        </BottomSheetView>
      </BottomSheetModal>

-> The error only occurs if the TextInput is connected to a useState. If I remove this: value={text} onChangeText={setText} everything is normal.

https://github.com/user-attachments/assets/0e7359b0-ea6f-466d-b2f2-311edb0282fd

Reproduction steps

Use the code above on Android with BottomSheetModal

Reproduction sample

https://snack.expo.dev/UwhwaCo1GT5m3B_F9dYwX

Relevant log output

WARN  [Reanimated] Reading from `value` during component render. Please ensure that you do not access the `value` property or use `get` method of a shared value while React is rendering a component.

If you don't want to see this message, you can disable the `strict` mode. Refer to:
https://docs.swmansion.com/react-native-reanimated/docs/debugging/logger-configuration for more details.

MarzyCoder avatar Feb 03 '25 20:02 MarzyCoder

Update: It seems that the issue is also on iOS!

MarzyCoder avatar Feb 05 '25 20:02 MarzyCoder

Yes i can confirm the same

marijang avatar Feb 10 '25 11:02 marijang

Any solutions or bugfixes for that, @gorhom ?

MarzyCoder avatar Feb 10 '25 12:02 MarzyCoder

Same issue for me but only if i put TextInput in

<BottomSheetModal> and <BottomSheetView>

Even if it's gorhom or default react textInput

nowayX avatar Feb 17 '25 02:02 nowayX

Same issue here

michel-lamarliere avatar Feb 17 '25 02:02 michel-lamarliere

Same issue here, any update ?

aldo025 avatar Feb 17 '25 07:02 aldo025

@gorhom

Same issue here, any update ?

MarzyCoder avatar Feb 17 '25 12:02 MarzyCoder

Same issue here, not sure why it's happening, any fixes @gorhom?

rajput7772 avatar Feb 18 '25 01:02 rajput7772

Same issue here

antoine-cottineau avatar Feb 28 '25 09:02 antoine-cottineau

Has anyone fixes for that? Like a PR? :)

MarzyCoder avatar Feb 28 '25 14:02 MarzyCoder

I found a way to fix the flickering issue. So basically we know that the issue is only with the "value" prop. So instead of using it, you need to use defaultValue and ALSO the "key" prop.

Why the key prop ? Let's imagine we want to change the value of the defaultValue after pressing a button or selecting another component that should have updated the value of the inputText. When using defaultValue, it's impossible to refresh the value unless... we use the 'key' property to reload the inputText and update the text in the inputText

Example :

  const [refreshTextInput, setRefreshTextInput] = useState(0);
  const handleUncontrolledReset = () => {
    setRefreshTextInput(prev => prev + 1);
  };

<TextInput
              key={refreshTextInput}
              label="Titre"
              style={styles.input}
              defaultValue={titre}
              mode='outlined'
              onChangeText={newTitre => setTitre(newTitre)}
 />

when I select a cards that I created, my inputText need to updates the text linked to the card. So I use the following example to reload the inputText

  useEffect(() => {
    if (selectedItem) {
      handleUncontrolledReset(); //Reload the textInput with the new value
    }
  }, [selectedItem])

And then No flikering issue and i can refresh the inputText normaly

nowayX avatar Mar 02 '25 14:03 nowayX

@nowayX works for me. Thank you! ๐Ÿ™

rajput7772 avatar Mar 02 '25 20:03 rajput7772

@nowayX works for me. Thank you! ๐Ÿ™

Don't forget to have unique Key for each inputText ! Np

nowayX avatar Mar 03 '25 01:03 nowayX

@nowayX Thank you for the workaround ๐Ÿ™.

aldo025 avatar Mar 04 '25 04:03 aldo025

@nowayX sorry for ping, i've been pulling my hair out for this issue until i found this post. how are you managing this issue across your app? i have a few bottom sheet modals in my app that use text input and i am wondering if i have to do this workaround on every component or if there's more of a "global" fix to this. Thanks : )

rochajulian avatar Mar 15 '25 01:03 rochajulian

drop-in replacement for the TextInput, based the solution from @nowayX

export default function MyTextInput(props: TextInputProps) {
  const { value, defaultValue, ...rest } = props

  return (
    <TextInput
      defaultValue={value ?? defaultValue ?? ''}
      {...rest}
    />
  );
}

congnd avatar Mar 15 '25 08:03 congnd

Same issue here

Splicer97 avatar Mar 19 '25 12:03 Splicer97

drop-in replacement for the TextInput, based the solution from @nowayX

export default function MyTextInput(props: TextInputProps) { const { value, defaultValue, ...rest } = props

return ( <TextInput defaultValue={value ?? defaultValue ?? ''} {...rest} /> ); }

This worked for me, thank you ๐ŸŽ‰

I just replaced the value prop with the defaultValue prop

<TextInput
     style={Style.input} 
     value={value} // => delete this
     defaultValue={value} // => add this
     onChangeText={e => onChangeText(e)}
    placeholder="Search"
    placeholderTextColor="#9F9E9B"
/>

ahmetcangurel avatar Mar 20 '25 06:03 ahmetcangurel

drop-in replacement for the TextInput, based the solution from @nowayX

export default function MyTextInput(props: TextInputProps) { const { value, defaultValue, ...rest } = props

return ( <TextInput defaultValue={value ?? defaultValue ?? ''} {...rest} /> ); }

It didn't fix the issue for me, but it made it more subtle on Android. It still happens, but less frequently. Are there any updates on a permanent solution?

any update?? @gorhom

rochajulian avatar Apr 03 '25 04:04 rochajulian

Iโ€™m having the same issue โ€” the app even crashes if I type or delete too quickly in the input. I tried using "defaultValue", but it didnโ€™t help.

hernanhawryluk avatar Apr 05 '25 18:04 hernanhawryluk

Iโ€™m having the same issue โ€” the app even crashes if I type or delete too quickly in the input. I tried using "defaultValue", but it didnโ€™t help.

@hernanhawryluk what error are you getting? my app is also crashing when i type too fast. My error is "NSInternalInconsistencyException: Handler for tag 92 does not exists"

rochajulian avatar Apr 05 '25 18:04 rochajulian

I just left the house, but before leaving I noticed that if I comment out the "BottomSheetBackdrop", meaning I disable it, the input works fine. I hope this helps as a temporary solution until @gorhom can address it.

hernanhawryluk avatar Apr 05 '25 18:04 hernanhawryluk

@hernanhawryluk interesting, so it also stopped crashing?

rochajulian avatar Apr 05 '25 18:04 rochajulian

if I comment out the "BottomSheetBackdrop", What did you mean?

MarzyCoder avatar Apr 05 '25 19:04 MarzyCoder

@rochajulian Yes, the issue was resolved by disabling the backdrop.

@MarzyCoder Let me explain:

I was originally using this component for the backdrop:

<BottomSheetBackdrop
        {...props}
        style={style}
        opacity={0.6}
        appearsOnIndex={1}
        disappearsOnIndex={-1}
        onPress={() => Keyboard.dismiss()}
/>

Then I replaced it with this custom one:

const CustomBackdrop: React.FC<BottomSheetBackdropProps> = ({
  style,
  ...props
}) => {
  const { close } = useBottomSheet();

  return (
    <Pressable
      onPress={() => {
        Keyboard.dismiss();
        close();
      }}
      style={{  ...StyleSheet.absoluteFillObject }}
    >
        <View
          style={{
              backgroundColor:
                 Platform.OS === "ios" ? "rgba(0, 0, 0, 0.3)" : "rgba(0, 0, 0, 0.6)",
              ...StyleSheet.absoluteFillObject,
          }}
        >
            {Platform.OS === "ios" && (
                 <BlurView
                      intensity={sizes.blur}
                      style={{ ...StyleSheet.absoluteFillObject }}
                 />
             )}
        </View>
</Pressable>

This change fixed the issue for me. I hope it helps!

hernanhawryluk avatar Apr 06 '25 16:04 hernanhawryluk

@hernanhawryluk do you mind sharing the version that you're on?

rochajulian avatar Apr 06 '25 16:04 rochajulian

"@gorhom/bottom-sheet": "^5.1.2",

hernanhawryluk avatar Apr 06 '25 16:04 hernanhawryluk

@hernanhawryluk Ty for your response! When I dont use this backdrop component, that is irrelevant for me, right?

MarzyCoder avatar Apr 06 '25 16:04 MarzyCoder

@MarzyCoder If youโ€™re not using a backdrop in the BottomSheet and still experiencing the issue, then itโ€™s likely caused by something else and still needs to be addressed.

In my case, I was experiencing what seemed to be the same issue, and I found that removing or replacing the <BottomSheetBackdrop /> component I was using as the backdrop resolved it for me.

hernanhawryluk avatar Apr 06 '25 17:04 hernanhawryluk