mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
fix: onChangeText should be called only once if changed via js in a multiline textinput (#45401)
Summary: Fixes [44566](https://github.com/facebook/react-native/issues/44566) Issue was onChangeText was called 5-6 times if maxLength was set in a multiline component and TextInput Value was changed via state update. `if (_maxLength) { NSInteger allowedLength = MAX( _maxLength.integerValue - (NSInteger)backedTextInputView.attributedText.string.length + (NSInteger)range.length, 0); if (text.length > allowedLength) { // If we typed/pasted more than one character, limit the text inputted. if (text.length > 1) { if (allowedLength > 0) { // make sure unicode characters that are longer than 16 bits (such as emojis) are not cut off NSRange cutOffCharacterRange = [text rangeOfComposedCharacterSequenceAtIndex:allowedLength - 1]; if (cutOffCharacterRange.location + cutOffCharacterRange.length > allowedLength) { // the character at the length limit takes more than 16bits, truncation should end at the character before allowedLength = cutOffCharacterRange.location; } } // Truncate the input string so the result is exactly maxLength NSString *limitedString = [text substringToIndex:allowedLength]; NSMutableAttributedString *newAttributedText = [backedTextInputView.attributedText mutableCopy]; // Apply text attributes if original input view doesn't have text. if (backedTextInputView.attributedText.length == 0) { newAttributedText = [[NSMutableAttributedString alloc] initWithString:[self.textAttributes applyTextAttributesToText:limitedString] attributes:self.textAttributes.effectiveTextAttributes]; } else { [newAttributedText replaceCharactersInRange:range withString:limitedString]; } backedTextInputView.attributedText = newAttributedText; _predictedText = newAttributedText.string; // Collapse selection at end of insert to match normal paste behavior. UITextPosition *insertEnd = [backedTextInputView positionFromPosition:backedTextInputView.beginningOfDocument offset:(range.location + allowedLength)]; [backedTextInputView setSelectedTextRange:[backedTextInputView textRangeFromPosition:insertEnd toPosition:insertEnd] notifyDelegate:YES]; [self textInputDidChange]; } return nil; // Rejecting the change. }}` This is the original code snippet. It was happening because of wrong check of maxLength with text length `if (text.length > allowedLength)` this should be `(text.length > _maxLength.integerValue)` and `if (allowedLength <= 0)` we should not change the string and fire `textInputDidChange` ## Changelog: [IOS] [FIXED] : Fixing maxLength check which was firing onChange multiple times For more details, see: https://reactnative.dev/contributing/changelogs-in-pull-requests Pull Request resolved: https://github.com/facebook/react-native/pull/45401 Test Plan: Tested in Ios Ran yarn test <img width="1661" alt="Screenshot 2024-07-12 at 1 00 28 PM" src="https://github.com/user-attachments/assets/fbad94a8-9989-4252-ad7d-e507d4eafd9e"> Reviewed By: sammy-SC Differential Revision: D59911745 Pulled By: cipolleschi fbshipit-source-id: 67410ec50d6a2415e568e1685699bfed02fd0a27
This commit is contained in:
committed by
Facebook GitHub Bot
parent
f8c13f601d
commit
d88dd14507
@@ -448,7 +448,7 @@ RCT_NOT_IMPLEMENTED(-(instancetype)initWithFrame : (CGRect)frame)
|
||||
_maxLength.integerValue - (NSInteger)backedTextInputView.attributedText.string.length + (NSInteger)range.length,
|
||||
0);
|
||||
|
||||
if (text.length > allowedLength) {
|
||||
if (text.length > _maxLength.integerValue) {
|
||||
// If we typed/pasted more than one character, limit the text inputted.
|
||||
if (text.length > 1) {
|
||||
if (allowedLength > 0) {
|
||||
@@ -459,6 +459,9 @@ RCT_NOT_IMPLEMENTED(-(instancetype)initWithFrame : (CGRect)frame)
|
||||
allowedLength = cutOffCharacterRange.location;
|
||||
}
|
||||
}
|
||||
if (allowedLength <= 0) {
|
||||
return nil;
|
||||
}
|
||||
// Truncate the input string so the result is exactly maxLength
|
||||
NSString *limitedString = [text substringToIndex:allowedLength];
|
||||
NSMutableAttributedString *newAttributedText = [backedTextInputView.attributedText mutableCopy];
|
||||
|
||||
Reference in New Issue
Block a user