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

When multiline=true, TextInput's onChangeText() callback may not fire.

Open ShadReyes opened this issue 1 year ago • 9 comments

Description

I am working on a chat feature in an app. It works like most chat features. If you type a message and submit, the text is cleared.

The problem is that after clearing the TextInput (input focus is maintained) the first character typed does not fire the onChangeText() callback.

This only is a problem when multiline=true

React Native Version

0.71.10

Output of npx react-native info

System: OS: macOS 13.4 CPU: (8) x64 Intel(R) Core(TM) i7-7700K CPU @ 4.20GHz Memory: 1.30 GB / 24.00 GB Shell: 5.9 - /bin/zsh Binaries: Node: 16.17.0 - /usr/local/bin/node Yarn: 1.22.19 - /usr/local/bin/yarn npm: 9.6.1 - /usr/local/bin/npm Watchman: Not Found Managers: CocoaPods: 1.12.1 - /usr/local/bin/pod SDKs: iOS SDK: Platforms: DriverKit 22.4, iOS 16.4, macOS 13.3, tvOS 16.4, watchOS 9.4 Android SDK: Not Found IDEs: Android Studio: Not Found Xcode: 14.3/14E222b - /usr/bin/xcodebuild Languages: Java: 18.0.2 - /usr/bin/javac npmPackages: @react-native-community/cli: Not Found react: Not Found react-native: Not Found react-native-macos: Not Found npmGlobalPackages: react-native: Not Found

Steps to reproduce

  1. Tap on TextInput
  2. Type "hello world"
  3. Press "submit". Text should be cleared
  4. Type "H"
  5. Press "submit". Text will not clear because onChangeText() will not fire.

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

const MessageInput = () => {
  const [message, setMessage] = useState('');

  const submit = () => {
    if(!message) {
      return;
    }
    setMessage('');
  }

  return (
    <>
        <TextInput
            placeholder='Message'
            placeholderTextColor={themes.texts.colors.placeholder}
            multiline={true}
            value={message}
            onChangeText={setMessage}
        />
        <Button title={'submit'} onPress={() => submit()}/>
    </>
  );
}

ShadReyes avatar Jun 08 '23 18:06 ShadReyes

:warning: Newer Version of React Native is Available!
:information_source: You are on a supported minor version, but it looks like there's a newer patch available - 0.71.10. Please upgrade to the highest patch for your minor or latest and verify if the issue persists (alternatively, create a new project and repro the issue in it). If it does not repro, please let us know so we can close out this issue. This helps us ensure we are looking at issues that still exist in the most recent releases.

github-actions[bot] avatar Jun 08 '23 18:06 github-actions[bot]

same issue. Reverting the below changes worked fine. https://github.com/facebook/react-native/commit/a804c0f22b4b11b3d9632dc59a6da14f6c4325e3

kkoudev avatar Jun 13 '23 06:06 kkoudev

Hi, I have the same issue (on iOS only, android works well) I can confirm I have the same issue with version 0.71.10

nmalzieu avatar Jun 14 '23 15:06 nmalzieu

I have confirmed for v0.71.10 as well that the issue still exists.

ShadReyes avatar Jun 15 '23 17:06 ShadReyes

This is an additional information. This issue has occurred from v0.71.8 below changes. https://github.com/facebook/react-native/commit/a804c0f22b4b11b3d9632dc59a6da14f6c4325e3

Therefore, it is possible to work around this by creating a patch that reverts this fix.

kkoudev avatar Jun 16 '23 10:06 kkoudev

Thanks @kkoudev , but I guess this fix was useful for another reason? (not firing onChange too often?)

nmalzieu avatar Jun 16 '23 10:06 nmalzieu

@nmalzieu Yes. If I revert the v0.71.8 fix, the issue (#36494) reoccurs. I can't decide which one should be prioritized because it depends on the application, If possible, the fix for #36494 should be re-fixed so that it no longer causes this issue.

kkoudev avatar Jun 16 '23 10:06 kkoudev

I've created a PR (#37958) to fix this issue without recurring the #36494 issue.

kkoudev avatar Jun 19 '23 10:06 kkoudev

Update: Fix has been merged https://github.com/facebook/react-native/commit/0c9c57a9f73294414d92428c5d2472dc1e1e5e96 (https://github.com/facebook/react-native/pull/37958#issuecomment-1620255303) 🎉

Thanks @kkoudev for fix 👍

@kelset can tell more about patches to latest and/or backports if needed :)

Pranav-yadav avatar Jul 08 '23 12:07 Pranav-yadav

ask for it in the release discussions

kelset avatar Jul 10 '23 09:07 kelset

Closed by #37958

cortinico avatar Jul 10 '23 11:07 cortinico

Have folks found that this has been fixed with 0.71.13? It sounds exactly like the bug I'm encountering, I've updated to 0.71.13, and am still experiencing the issue.

What's also throwing me off is that I don't see the tag for 0.71.13 on the commit page, unlike what the documentation says should happen when a fix is released.

ajyang818 avatar Sep 11 '23 02:09 ajyang818

Have folks found that this has been fixed with 0.71.13?

@ajyang818 this fix is on main which means will land in 0.73. Where have you found that this is included in 0.71.x?

cortinico avatar Sep 11 '23 13:09 cortinico

Have folks found that this has been fixed with 0.71.13?

@ajyang818 this fix is on main which means will land in 0.73. Where have you found that this is included in 0.71.x?

The fix and reference to this issue is stated in the 0.71.13 change log. I need to verify the fix myself @ajyang818.

ShadReyes avatar Sep 11 '23 17:09 ShadReyes

Right, I was referring to Should we release 0.71.13? - am I interpreting that discussion correctly?

ajyang818 avatar Sep 11 '23 23:09 ajyang818

If I look at the commit, and find the file that's supposed to have the change in my node_modules/, I do in fact see the change - this is in file RCTBackedTextInputDelegateAdapter.m. I'm guessing if I see it there, that means the change did come with 0.71.13, is that fair?

ajyang818 avatar Sep 11 '23 23:09 ajyang818

@ajyang818 I can confirm (after initializing a few React-Native projects) this issue was fixed in v0.71.13 and >= v0.72.2. Thanks @kkoudev . Have you deleted your node_modules folders and re-installed your app dependencies?

ShadReyes avatar Sep 12 '23 21:09 ShadReyes

@ShadReyes Unfortunately still experiencing this bug on both 0.71.13 and 0.72.2. I've tried deleting node_modules and re-installing via yarn with both versions.

My code is slightly different as I've been trying various permutations of async to try to fix this issue:

    const earlierFunctionHandlingTextInputSubmission = async (...) => {
        ...
        await clearMainInput()
        ...
    }

    const clearMainInput = async () => {
        console.log("Calling clearMainInput")
        await setUserMessage('');
    }

    const textInputOnChange = ({ nativeEvent: { eventCount, target, text} }) => {
        console.log("onChange called");
        console.log("new text: " + JSON.stringify(text));
        setUserMessage(text);
    }

    <Swipeable ... >
        <TouchableOpacity ...>
            <TextInput
                    ref={combinedRef}
                    multiline
                    editable
                    placeholder='Type message here!'
                    placeholderTextColor={'lightgray'}
                    value={userMessage}
                    numberOfLines={50}
                    onChange={textInputOnChange}
                />
    ...

The repro with this is very similar to what the original poster had:

  1. Type message into TextInput - I'll see textInputOnChange fire with every character typed, including the first one
  2. Submit the TextInput (in my case, it involves swiping the input)
  3. My fancifully named earlierFunctionHandlingTextInputSubmission runs, which clears the TextInput
  4. Type 1 character - textInputOnChange does NOT fire
  5. Type 2nd character - textInputOnChange DOES fire, and fires for anything typed from then on

I've also noticed that in step 4, if you paste something instead of type, textInputOnChange also does NOT fire.

ajyang818 avatar Sep 20 '23 01:09 ajyang818

@ajyang818 I am unsure what you issue is then. I just tested the following code and onChange does fire now when following the same steps. This is RN v0.72.4

function App(): JSX.Element {
  const [message, setMessage] = useState('');

  const submit = () => {
    if (!message) {
      return;
    }
    setMessage('');
  };

  return (
    <SafeAreaView>
      <TextInput
        placeholder="Message"
        multiline={true}
        editable={true}
        placeholderTextColor={'lightgray'}
        numberOfLines={50}
        value={message}
        onChangeText={setMessage}
      />
      <Button title={'submit'} onPress={() => submit()} />
    </SafeAreaView>
  );
}

export default App;

Sorry I can't be more help. I would just make sure your project and package.json is setup correctly. If you are working on a monorepo, this is especially important as there is a possibility of having different versions of react-native packages in different node_module folders. Though, I'm guessing you already know all of this.

ShadReyes avatar Sep 20 '23 19:09 ShadReyes

@ShadReyes I did not know that, and appreciate your help! You may be onto something that there's something weird about how my project is set up. I'm using expo go, but am manually upgrading the react-native version with yarn - would that mess things up?

After reading your last message, I tried the following:

  • Updating to 0.72.4 - didn't seem to fix it
  • Creating a simpler repro case in my app on a different screen, very close to yours - this also has the buggy behavior
  • Tried checking for other versions of react-native by running npm ls react-native - seems to check out, with only 0.72.4 showing up:
├─┬ @emotion/[email protected]
│ └── [email protected] deduped
├─┬ @react-native-async-storage/[email protected]
│ └── [email protected] deduped
├─┬ @react-navigation/[email protected]
│ ├─┬ @react-navigation/[email protected]
│ │ └── [email protected] deduped
│ └── [email protected] deduped
├─┬ @react-navigation/[email protected]
│ └── [email protected] deduped
├─┬ [email protected]
│ └── [email protected] deduped
├─┬ [email protected]
│ ├─┬ [email protected]
│ │ └── [email protected] deduped
│ └─┬ [email protected]
│   └── [email protected] deduped
├─┬ [email protected]
│ ├─┬ [email protected]
│ │ └── [email protected] deduped
│ └── [email protected] deduped
├─┬ [email protected]
│ └── [email protected] deduped
├─┬ [email protected]
│ └── [email protected] deduped
├─┬ [email protected]
│ └── [email protected] deduped
├─┬ [email protected]
│ └── [email protected] deduped
├─┬ [email protected]
│ └── [email protected] deduped
├─┬ [email protected]
│ └── [email protected] deduped
├─┬ [email protected]
│ └── [email protected] deduped
├─┬ [email protected]
│ └─┬ @react-native/[email protected]
│   └── [email protected] deduped
├─┬ [email protected]
│ ├─┬ @react-navigation/[email protected]
│ │ └─┬ [email protected]
│ │   └── [email protected] deduped
│ └── [email protected] deduped
└─┬ [email protected]
  └── [email protected] deduped

Would there be somewhere else to check if my code is somehow still drawing on an older version of react-native?

ajyang818 avatar Sep 21 '23 01:09 ajyang818

@ajyang818 As long as you ran that command from the root then that should be it. If it is a monorepo and you ran it from the root, you would need to make sure package.json has the workspace set up so that npm/yarn install trickles down to all the children package.json.

I have one last thing you can try! I just realized that in an early comment I said to delete your node_modules folders and reinstall. I completely missed including that you should delete the iOS pods folder and re-run pod install. If that doesn't work, my last advice would be to delete the pods folder and podfile.lock and rerun pod install.

I apologize. I never asked your level of experience in RN. I don't want to assume that you do or do not know to try any of these things.

That is the last bit of help I know to give. So I really hope that is the problem. Let me know what your results are!

ShadReyes avatar Sep 21 '23 16:09 ShadReyes

@ShadReyes I forgot to try pod install! Unfortunately that didn't help. But I appreciate your trying to help! I'll put this aside for now and come back to it later.

ajyang818 avatar Sep 22 '23 00:09 ajyang818