Skip to content

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

Description

@ShadReyes

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()}/>
    </>
  );
}

Activity

  1. github-actions commented on Jun 8, 2023

    @github-actions
    ⚠️ Newer Version of React Native is Available!
    ℹ️ 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.
  2. kkoudev commented on Jun 13, 2023

    @kkoudev
    Contributor

    same issue.
    Reverting the below changes worked fine.
    a804c0f

  3. nmalzieu commented on Jun 14, 2023

    @nmalzieu

    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

  4. ShadReyes commented on Jun 15, 2023

    @ShadReyes
    Author

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

  5. kkoudev commented on Jun 16, 2023

    @kkoudev
    Contributor

    This is an additional information.
    This issue has occurred from v0.71.8 below changes.
    a804c0f

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

  6. nmalzieu commented on Jun 16, 2023

    @nmalzieu

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

  7. kkoudev commented on Jun 16, 2023

    @kkoudev
    Contributor

    @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.

  8. kkoudev commented on Jun 19, 2023

    @kkoudev
    Contributor

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

  9. Pranav-yadav commented on Jul 8, 2023

    @Pranav-yadav
    Contributor

    Update: Fix has been merged 0c9c57a (#37958 (comment)) 🎉

    Thanks @kkoudev for fix 👍

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

  10. 8 remaining items

  11. allenjhyang commented on Sep 11, 2023

    @allenjhyang

    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.

  12. cortinico commented on Sep 11, 2023

    @cortinico
    Contributor

    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?

  13. ShadReyes commented on Sep 11, 2023

    @ShadReyes
    Author

    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.

  14. allenjhyang commented on Sep 11, 2023

    @allenjhyang

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

  15. allenjhyang commented on Sep 11, 2023

    @allenjhyang

    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?

  16. ShadReyes commented on Sep 12, 2023

    @ShadReyes
    Author

    @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?

  17. allenjhyang commented on Sep 20, 2023

    @allenjhyang

    @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.

  18. ShadReyes commented on Sep 20, 2023

    @ShadReyes
    Author

    @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.

  19. allenjhyang commented on Sep 21, 2023

    @allenjhyang

    @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/native@11.11.0
    │ └── react-native@0.72.4 deduped
    ├─┬ @react-native-async-storage/async-storage@1.18.2
    │ └── react-native@0.72.4 deduped
    ├─┬ @react-navigation/native-stack@6.9.12
    │ ├─┬ @react-navigation/elements@1.3.17
    │ │ └── react-native@0.72.4 deduped
    │ └── react-native@0.72.4 deduped
    ├─┬ @react-navigation/native@6.1.6
    │ └── react-native@0.72.4 deduped
    ├─┬ react-native-device-info@10.6.0
    │ └── react-native@0.72.4 deduped
    ├─┬ react-native-elements@3.4.3
    │ ├─┬ react-native-ratings@8.0.4
    │ │ └── react-native@0.72.4 deduped
    │ └─┬ react-native-size-matters@0.3.1
    │   └── react-native@0.72.4 deduped
    ├─┬ react-native-flash-message@0.4.1
    │ ├─┬ react-native-iphone-screen-helper@2.0.3
    │ │ └── react-native@0.72.4 deduped
    │ └── react-native@0.72.4 deduped
    ├─┬ react-native-gesture-handler@2.12.1
    │ └── react-native@0.72.4 deduped
    ├─┬ react-native-image-picker@5.3.1
    │ └── react-native@0.72.4 deduped
    ├─┬ react-native-paper@5.8.0
    │ └── react-native@0.72.4 deduped
    ├─┬ react-native-purchases@6.0.0
    │ └── react-native@0.72.4 deduped
    ├─┬ react-native-safe-area-context@4.6.3
    │ └── react-native@0.72.4 deduped
    ├─┬ react-native-safe-area-view@1.1.1
    │ └── react-native@0.72.4 deduped
    ├─┬ react-native-screens@3.22.1
    │ └── react-native@0.72.4 deduped
    ├─┬ react-native@0.72.4
    │ └─┬ @react-native/virtualized-lists@0.72.8
    │   └── react-native@0.72.4 deduped
    ├─┬ react-navigation@4.4.4
    │ ├─┬ @react-navigation/native@3.8.4
    │ │ └─┬ react-native-safe-area-view@0.14.9
    │ │   └── react-native@0.72.4 deduped
    │ └── react-native@0.72.4 deduped
    └─┬ react-redux@8.0.5
      └── react-native@0.72.4 deduped
    

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

  20. ShadReyes commented on Sep 21, 2023

    @ShadReyes
    Author

    @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!

  21. allenjhyang commented on Sep 22, 2023

    @allenjhyang

    @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.

  22. zhe1ka commented on Jun 11, 2024

    @zhe1ka

    confirm. i had react-native: 0.72.0 - the issue is reproducible. upgraded to 0.72.4 - the issue is gone!

  23. HasanElfalt commented on Dec 29, 2024

    @HasanElfalt

    the same issue with react native 0.75.4

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

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions