react-native
react-native copied to clipboard
`maxLength` of TextInput does not work when value is changed after state update
Description
maxLength of Text Input is not working when value is changed after state update. It works as expected when input is given with keyboard.
<TextInput style={styles.textInput} value={description} maxLength={10} onChangeText={text => setDescription(text)} />
Steps to reproduce
- Set
maxLengthof TextInput to any non zero number - Store any text in state
- Use text stored in state as value in TextInput
- Update the state with text length greater than
maxLength - TextInput will have text which has length greater than given
maxLength
React Native Version
0.74.2
Affected Platforms
Runtime - iOS
Output of npx react-native info
System:
OS: macOS 13.5.1
CPU: (10) arm64 Apple M1 Max
Memory: 73.36 MB / 32.00 GB
Shell:
version: "5.9"
path: /bin/zsh
Binaries:
Node:
version: 18.12.0
path: ~/.nvm/versions/node/v18.12.0/bin/node
Yarn:
version: 3.6.4
path: /opt/homebrew/bin/yarn
npm:
version: 8.19.2
path: ~/.nvm/versions/node/v18.12.0/bin/npm
Watchman: Not Found
Managers:
CocoaPods:
version: 1.14.3
path: /Users/kunal.chavhan/.rvm/gems/ruby-3.2.2/bin/pod
SDKs:
iOS SDK:
Platforms:
- DriverKit 23.0
- iOS 17.0
- macOS 14.0
- tvOS 17.0
- watchOS 10.0
Android SDK: Not Found
IDEs:
Android Studio: Jellyfish 2023.3.1 Patch 2 Jellyfish 2023.3.1 Patch 2
Xcode:
version: 15.0/15A240d
path: /usr/bin/xcodebuild
Languages:
Java:
version: 17.0.10
path: /usr/bin/javac
Ruby:
version: 3.2.2
path: /Users/kunal.chavhan/.rvm/rubies/ruby-3.2.2/bin/ruby
npmPackages:
"@react-native-community/cli": Not Found
react:
installed: 18.2.0
wanted: 18.2.0
react-native:
installed: 0.74.2
wanted: 0.74.2
react-native-macos: Not Found
npmGlobalPackages:
"*react-native*": Not Found
Android:
hermesEnabled: true
newArchEnabled: false
iOS:
hermesEnabled: true
newArchEnabled: false
Stacktrace or Logs
NA
Reproducer
https://github.com/kunalchavhan/rn-textinput-maxlength-reproducer
Screenshots and Videos
https://github.com/facebook/react-native/assets/61144478/4a377ec3-e60a-46ad-b54d-c6362ebd8622
I was debugging this and found that this method is getting called whenever text is updated from react's state change. This method then calls setAttributedString which then sets the text. I could not find any checks here for maxLength prop.
When input is received from keyboard this method is called which has maxLength prop check.
Any reason for not checking maxLength prop here also?
@sammy-SC could you please take a look into this? Thank you for your time.
I was debugging this and found that this method is getting called whenever text is updated from react's state change. This method then calls
setAttributedStringwhich then sets the text. I could not find any checks here formaxLengthprop.When input is received from keyboard this method is called which has
maxLengthprop check.Any reason for not checking
maxLengthprop here also?
The code you are linking is for the new architecture but your repro is with the old architecture. For the old architecture, maxLength is handled here. It appears maxLength is not taken account for when the update comes from React.
This can be annoying but there is a simple workaround if this is blocking you. When setting text from React, you can check for the length of new text value and shorten it if it goes over the maxLength. maxLength is important for the updates to TextInput coming from native, because there your JavaScript code doesn't have a a chance to run. Thanks to maxLength prop, you have a chance to prevent iOS from painting TextInput with value that is longer than maxLength.
The code you are linking is for the new architecture but your repro is with the old architecture. For the old architecture, maxLength is handled here. It appears maxLength is not taken account for when the update comes from React.
This can be annoying but there is a simple workaround if this is blocking you. When setting text from React, you can check for the length of new text value and shorten it if it goes over the maxLength. maxLength is important for the updates to TextInput coming from native, because there your JavaScript code doesn't have a a chance to run. Thanks to maxLength prop, you have a chance to prevent iOS from painting TextInput with value that is longer than maxLength.
Thank you for the clarification and sorry for wrong linking of code. I pushed repro for new architecture here.
Thank you for suggesting workaround. I have checked that the maxLength prop works for updates from React on android. Would it be possible to have the same behaviour on iOS also?
Thank you for the clarification and sorry for wrong linking of code. I pushed repro for new architecture here.
Thank you for suggesting workaround. I have checked that the
maxLengthprop works for updates from React on android. Would it be possible to have the same behaviour on iOS also?
@sammy-SC if you agree that iOS should handle maxLength on updates from react, can I try to resolve this?
Issue still appears on iOS with react-native version 0.76.1. Any updates?
+1 still an issue on 76.5. The maxLength property is not working for me.
+1 maxLength property is not working on v0.76.5.
@vanBerloDevelopments @ChristopherGabba @johaan22 Are you all sure you're hitting the specific issue of maxLength not working after state update? Or are you hitting the general issue of maxLength not working at all on iOS? If it's the latter a fix has already been merged and will be released in 0.78. See https://github.com/facebook/react-native/issues/47563
@Tobbe, I'm honestly not sure which it is. I'm definitely using TextInputs like I have always used them:
const [textValue, setTextValue] = useState("")
<TextInput
maxLength={10}
value={textValue}
onChangeText={setTextValue}
/>
And it lets me just type straight past 10 with not even a bobble. I have not tested this on Android, but it is for sure happening on iOS.
@ChristopherGabba, yeah, that's #47563. We'll have to wait for 0.78 to get access to the fix
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.
This issue was closed because it has been stalled for 7 days with no activity.