question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

TextInput onChangeText is called with empty text if maxLength is exceeded on iOS

See original GitHub issue

Description

If the max length of a controlled TextInput is exceeded on iOS onChangeText will get called with an empty string. We noticed this issue when our users added an emoji as the last character in a TextInput. We only see the issue on iOS, on Android the the emoji can not be added. Since emojis are counted as two chars I’m guessing the emoji is causing the text to have length maxLength+1 and that is causing issues on iOS.

Using an uncontrolled TextInput the emoji is replace with the last character in the screenshot below but keeps it’s value. Screenshot 2020-04-28 at 14 48 00

React Native version:

0.61.4

Steps To Reproduce

Provide a detailed list of steps that reproduce the issue.

  1. Create a controlled TextInput with a maxLength
  2. Input text until you reach maxLength - 1
  3. Add a emoji

Expected Results

Same behaviour as on Android that the emoji is not accepted as input.

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

https://snack.expo.io/8x3dBwzJe

Issue Analytics

  • State:open
  • Created 3 years ago
  • Reactions:7
  • Comments:12

github_iconTop GitHub Comments

3reactions
ghostcommented, Mar 20, 2021

As a workaround I’ve removed maxLength prop and added the following code to the onChangeText callback:

onChangeText={value => {
    if (value.length <= maxLength) {
        setNewValue(value)
    }
}}

It minimizes the chances of the bug happening but doesn’t fix it.

2reactions
AlbertVilaCalvocommented, Feb 23, 2022

I’ve found a workaround that fixes the issue:

import * as React from 'react'
import { Platform, TextInput, TextInputProps } from 'react-native'

export interface TextInputFixedProps extends TextInputProps {
  onChangeText: (text: string) => void
}

/**
 * Workaround for https://github.com/facebook/react-native/issues/28774
 * and https://github.com/status-im/status-react/issues/12919.
 *
 * Fixes `onChange` clearing the whole input when an emoji is typed as the last
 * character when having `maxLength`. This happens on iOS only.
 *
 * Requires `onChangeText` to be set.
 */
export function TextInputFixed(props: TextInputFixedProps) {
  if (Platform.OS === 'ios') {
    return (
      <TextInput
        {...props}
        onChangeText={undefined}
        onChange={(event) => {
          const newText = event.nativeEvent.text
          const currentText = event._dispatchInstances.memoizedProps.text
          const clearsInput =
            props.maxLength &&
            currentText.length === props.maxLength - 1 &&
            newText.length === 0
          if (!clearsInput) {
            props.onChangeText(newText)
          }
        }}
      />
    )
  } else {
    return <TextInput {...props} />
  }
}

It’s a bit ugly to access the private _dispatchInstances, but it does work.

I’m using React Native ~0.63.4.

Read more comments on GitHub >

github_iconTop Results From Across the Web

React Native to limit lines in TextInput - Stack Overflow
For standard text fontSize, giving maxHeight={60} will make TextInput scrollable after 3 lines. This is good for IOS - for Android you can...
Read more >
When MaxLength is reached switch to another TextInput
I have a canvas app that includes two different text inputs. On the first text input I assigned the MaxLength to be 20...
Read more >
TextInput - ReactXP
In the first mode, the contents of the text input are static and are specified by the value prop. Any attempt to modify...
Read more >
React Native Text Input Component - GeeksforGeeks
maxLength : It is used when we do not want to exceed the particular number of characters. So we provide a fixed maximum...
Read more >
TextInput QML Type | Qt Quick 6.4.1
TextInput does not have vertical alignment, as the natural height is exactly the height of the single line of text. If you set...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found