Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TextInput's onKeyPress and onChangeText order of execution is inconsistent across platforms - iOS and Android #31436

Open
yuliankarapetkov opened this issue Apr 26, 2021 · 7 comments

Comments

@yuliankarapetkov
Copy link

yuliankarapetkov commented Apr 26, 2021

Description

onKeyPress is being called before onChangeText on iOS and after it on Android.

React Native version:

0.63 (Expo SDK 41) - see Snack

Expected Results

Order of execution should be the same across platforms, e.g. onKeyPress should always occur first, regardless of the OS.

Snack, code example, screenshot, or link to a repository:

Snack example

image

@bychung
Copy link

bychung commented Jun 15, 2021

Same issue here.

@ngasull
Copy link

ngasull commented Dec 8, 2021

Still an issue in react-native 0.64.3 with expo 43.

This really surprises me because it makes many editing behaviors basically impossible with react native like having a multiline input with custom behavior when pressing return.

Does anybody have more insight or a real workaround for this?

@jbrowning
Copy link

Still an issue on react-native 0.67.3

@landabaso
Copy link

landabaso commented Jul 19, 2022

Still an issue on react-native 0.69.

As a workaround you can defer the call for the next execution thread:

<TextInput>
    onChangeText={text => {
      setTimeout(() => onChangeText(text), 0);
    }}
</TextInput>

Although it's flickery. A better alternative is to keep track of an additional deferred variable deferredText and use that one in onKeyPress:

  const [text, setText] = React.useState('');
  const [deferredText, setDeferredText] = React.useState('');

with:

  <TextInput>
    value={text}
    onChangeText={onChangeText}
    onKeyPress={onKeyPress}
  </TextInput>

and:

  const onChangeText = newText => {
    if (newText !== text) setText(newText);
    setTimeout(() => {
      if (newText !== deferredText) setDeferredText(newText);
    }, 0);
  };

  const onKeyPress = ({nativeEvent}) => {
       //Here you can use deferredText instead of text to have similar behaviour in Android, Web & iOS.
       //If you want, you can use deferredText only on Android and text in other platforms. But using deferredText works just fine across all platforms I tested.
  }

Copy link

This issue is stale because it has been open 180 days with no activity. Remove stale label or comment or this will be closed in 7 days.

@github-actions github-actions bot added the Stale There has been a lack of activity on this issue and it may be closed soon. label Jan 14, 2024
@fabOnReact
Copy link
Contributor

Do you still experience this issue?

I have four years of experience maintaining facebook/react-native and I specialize in the Text and TextInput components. I currently have 58 facebook/react-native PRs.

If you still experience this issue, I will prepare a patched release with the fix.

Thanks a lot

@github-actions github-actions bot removed the Stale There has been a lack of activity on this issue and it may be closed soon. label Jan 18, 2024
@longb1997
Copy link

Do you still experience this issue?

I have four years of experience maintaining facebook/react-native and I specialize in the Text and TextInput components. I currently have 58 facebook/react-native PRs.

If you still experience this issue, I will prepare a patched release with the fix.

Thanks a lot

i still see it, please update a patch
Thank you

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

7 participants