Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ReactNative's state update via this.setState breaks text input mode for Korean, Chinese, Japanese characters in 0.54 and 0.55 #19339

Closed
daesan opened this issue May 18, 2018 · 17 comments
Labels
Impact: Regression Describes a behavior that used to work on a prior release, but stopped working recently. Platform: iOS iOS applications. Resolution: Locked This issue was locked by the bot.

Comments

@daesan
Copy link
Contributor

daesan commented May 18, 2018

Environment

Environment:
OS: macOS High Sierra 10.13.4
Node: 6.11.0
Yarn: Not Found
npm: 3.10.10
Watchman: Not Found
Xcode: Xcode 9.3 Build version 9E145
Android Studio: 3.0 AI-171.4443003

Packages: (wanted => installed)
react: ^16.3.1 => 16.3.2
react-native: ^0.55.4 => 0.55.4

Steps to Reproduce

This issue has been reported number of times already. #19313 #18403 #19104 #19337 #12599 #18379 #18767 #18260

However, most of them reported the issue as being the TextInput bug whereas the real bug seems to lie with ReactNative's view re-rendering logic in iOS. This report is to unify them under a more proper title so that someone who is more likely to recognize the root cause of this issue can pay attention.

If there is a TextInput tag in jsx file and its onChange or onChangeText callback has this.setState() call, Korean, Chinese, Japanese characters (which have multi-stage character input mode) are not input correctly.

In caes of Hangul(Korean), if the cursor is at the end of the text, the input is handled properly. However, if the cursor is at the beginning or is in the middle of the text, the input character parts are not combined as they should be. The parts of a character that should form a single character are input separately by themselves.

To reproduce, just type some Korean characters in TextInput, such as "하늘". Then move the cursor to the beginning of the text, and then type any text. Let's say I typed "파란" this time.

Expected Behavior

The text should be input like "파란하늘" (meaning blue sky)

Actual Behavior

However, as of RN version 0.54 and 0.55, the text is input like "ㅍㅏㄹㅏㄴ하늘"

Chinese characters and Japanese kanji characters are input by first entering romanzi to specify the pronounciation and then the user select a character from a list of Chinese characters popup that appears. However, this popup does not appear at all, as demonstrated in #18403.

Korean, Chineses, Japanese characters input is handled by multi-state IM mode. However, setState => view re-rendering cycle of ReactNative in v0.54 and v0.55 seems to reset the "character input is in progress" IM mode, thus causing incomplete and/or no characters to be entered into TextInput field.

This is a rather serious issue for Korean, Chinese, Japanese developers who have no options but to stick with v0.53 or below. (0.53 is particularly unstable version so I am stuck using v0.52.3) If anyone can guess where this issue might be stemming from, please share your opinions. It would be very much appreciated. Thank you.

@hramos hramos added the Impact: Regression Describes a behavior that used to work on a prior release, but stopped working recently. label May 18, 2018
@daesan
Copy link
Contributor Author

daesan commented May 18, 2018

I forgot to mention that this is an iOS only issue.

@RebelBIrd

This comment has been minimized.

@mandrigin
Copy link

@daesan can you reproduce this issue on react-native 0.56.0? I can't anymore...

@daesan
Copy link
Contributor Author

daesan commented Jul 18, 2018

@mandrigin Thank you for working on this issue! Unfortunately, I can reproduce the issue with both single-line TextInput and multi-line TextInput on RN 0.56.0...

@gcmsg
Copy link

gcmsg commented Aug 2, 2018

Any updates on this issue? This only happens when you use iOS default input method, if you use third party input method, this problem will disappear.

@AndrewJack
Copy link
Contributor

Does this commit fix it? 892212b

@rarira
Copy link

rarira commented Sep 16, 2018

Does this commit fix it? 892212b
@AndrewJack

in RN 0.57 , Japanese solved but not Korean

@KouSyurei
Copy link

Also encountered such a problem, it is suggested that using onCompositionStart/Update/onCompositionStartEndURL

@mandrigin
Copy link

@rarira @KouSyurei We experienced this issue ourselves and I tried to workaround this issue for Korean (but only for the multi-line text fields).
Here is a PR for that: #19809
If that solves your issues, please ping me, then I can extend it to the single-line text fields too.

PS: it would be nice to receive any feedback on that PR, from the core contributors. It's a bit hacky, I know, and if there is a better way to fix it, I'd ❤️ to know that and I can commit to fix it. Being able to use a non-patched React Native version is worth it 🙂

@mandrigin
Copy link

Here is a fix for single-line text fields: #22546

@leiz-me
Copy link

leiz-me commented Dec 10, 2018

Facing a similar issue when trying to put a <Text /> inside of <TextInput /> to get custom styles of text while typing.
Something like

<TextInput ...props>
  <Text style={styles.customTextStyle}>{this.state.textinput}<Text/>
</TextInput>.

While typing Chinese pinyin like haha("哈哈"), press h, then the input goes to h'aha', which the first h is turned to a simple alphabetical character.

@mandrigin
Copy link

@leiz-me can you check if you can reproduce this issue on this React-Native branch?
#22546

@leiz-me
Copy link

leiz-me commented Dec 10, 2018

@mandrigin Will check it out. My project is based on 0.51, so I need some time.

@leiz-me
Copy link

leiz-me commented Dec 11, 2018

@mandrigin Upgraded my project to RN 0.57.7 last night. And interesting thing is, on 0.57.7, the issue I described above is fixed. And I didn't touch the RN branch you mentioned yet.

I am not sure if the issue I got is related to your problem. Sorry if I am not helpful.

@mandrigin
Copy link

@leiz-me I'm glad that you don't have this issue. It should for sure be partially fixed in 0.57.7 (for multi-line text fields). Single line text fields might still be affected until #22546 is merged.

kelset pushed a commit that referenced this issue Dec 12, 2018
…#19809)

Summary:
iOS-specific.
For languages with complex input (such as Japanese or Chinese), a user has to type multiple characters that are then merged into a single one.
If `-[UITextView setAttributedString:]` is used while the user is still typing, it resets the input and characters are not being treated as typed together.

This PR avoids calling this method if possible, replacing it by just copying the attributes if the string has not been changed. That preserves the state and user can continue to type Korean or Chinese characters.

Fixes #19339

<!--
  Required: Write your motivation here.
  If this PR fixes an issue, type "Fixes #issueNumber" to automatically close the issue when the PR is merged.
-->

<!--
  Required: Write your test plan here. If you changed any code, please provide us with
  clear instructions on how you verified your changes work. Bonus points for screenshots and videos!
-->

Essentially, the steps to reproduce are described in [the issue](#19339):

1. Type some Korean characters in TextInput, such as "하늘" (buttons `ㅎ`,`ㅏ`,`ㄴ`,`ㅡ`,`ㄹ`).
2. Then move the cursor to the beginning of the text, type "파란" (buttons `ㅍ`,`ㅏ`,`ㄹ`,`ㅏ`,`ㄴ`) this time.

**Behaviour before this fix (broken)**
Actual text: `ㅍㅏㄹㅏㄴ하늘`.
Expected text: `파란하늘`.
Characters aren't combined properly.

![ezgif com-resize](https://user-images.githubusercontent.com/466427/41613572-4256dda8-73f6-11e8-99a9-0ab833202b95.gif)

**Behaviour after this fix (correct)**
Actual text: `파란하늘`.
Expected text: `파란하늘`.
Characters are combined, the same behaviour is in vanilla iOS `UITextView`.

![input-with-fix](https://user-images.githubusercontent.com/466427/41613526-1aae2284-73f6-11e8-87f2-c1cef51cd83a.gif)

<!--
  Does this PR require a documentation change?
  Create a PR at https://github.com/facebook/react-native-website and add a link to it here.
-->

<!--
  Required.
  Help reviewers and the release process by writing your own release notes. See below for an example.
-->

[IOS] [BUGFIX] [TextView] - Fix Korean/Chinese/Japanese input for multiline TextView on iOS.

<!--
  **INTERNAL and MINOR tagged notes will not be included in the next version's final release notes.**

    CATEGORY
  [----------]      TYPE
  [ CLI      ] [-------------]    LOCATION
  [ DOCS     ] [ BREAKING    ] [-------------]
  [ GENERAL  ] [ BUGFIX      ] [ {Component} ]
  [ INTERNAL ] [ ENHANCEMENT ] [ {Filename}  ]
  [ IOS      ] [ FEATURE     ] [ {Directory} ]   |-----------|
  [ ANDROID  ] [ MINOR       ] [ {Framework} ] - | {Message} |
  [----------] [-------------] [-------------]   |-----------|

 EXAMPLES:

 [IOS] [BREAKING] [FlatList] - Change a thing that breaks other things
 [ANDROID] [BUGFIX] [TextInput] - Did a thing to TextInput
 [CLI] [FEATURE] [local-cli/info/info.js] - CLI easier to do things with
 [DOCS] [BUGFIX] [GettingStarted.md] - Accidentally a thing/word
 [GENERAL] [ENHANCEMENT] [Yoga] - Added new yoga thing/position
 [INTERNAL] [FEATURE] [./scripts] - Added thing to script that nobody will see
-->
Pull Request resolved: #19809

Differential Revision: D13326614

Pulled By: shergin

fbshipit-source-id: 6a5cab3f7290f0f623a6f4c29353a573eb321b0b
@rarira
Copy link

rarira commented Dec 16, 2018

@mandrigin thanks for your effort, and after updating 0.57.8, there is no Korean multiline textinput issue!.. 0.57.7 still had the problem. Thanks!

@mandrigin
Copy link

@rarira great to hear! I hope the fix for single-line text fields will land soon too!

grabbou pushed a commit that referenced this issue Dec 17, 2018
…#19809)

Summary:
iOS-specific.
For languages with complex input (such as Japanese or Chinese), a user has to type multiple characters that are then merged into a single one.
If `-[UITextView setAttributedString:]` is used while the user is still typing, it resets the input and characters are not being treated as typed together.

This PR avoids calling this method if possible, replacing it by just copying the attributes if the string has not been changed. That preserves the state and user can continue to type Korean or Chinese characters.

Fixes #19339

<!--
  Required: Write your motivation here.
  If this PR fixes an issue, type "Fixes #issueNumber" to automatically close the issue when the PR is merged.
-->

<!--
  Required: Write your test plan here. If you changed any code, please provide us with
  clear instructions on how you verified your changes work. Bonus points for screenshots and videos!
-->

Essentially, the steps to reproduce are described in [the issue](#19339):

1. Type some Korean characters in TextInput, such as "하늘" (buttons `ㅎ`,`ㅏ`,`ㄴ`,`ㅡ`,`ㄹ`).
2. Then move the cursor to the beginning of the text, type "파란" (buttons `ㅍ`,`ㅏ`,`ㄹ`,`ㅏ`,`ㄴ`) this time.

**Behaviour before this fix (broken)**
Actual text: `ㅍㅏㄹㅏㄴ하늘`.
Expected text: `파란하늘`.
Characters aren't combined properly.

![ezgif com-resize](https://user-images.githubusercontent.com/466427/41613572-4256dda8-73f6-11e8-99a9-0ab833202b95.gif)

**Behaviour after this fix (correct)**
Actual text: `파란하늘`.
Expected text: `파란하늘`.
Characters are combined, the same behaviour is in vanilla iOS `UITextView`.

![input-with-fix](https://user-images.githubusercontent.com/466427/41613526-1aae2284-73f6-11e8-87f2-c1cef51cd83a.gif)

<!--
  Does this PR require a documentation change?
  Create a PR at https://github.com/facebook/react-native-website and add a link to it here.
-->

<!--
  Required.
  Help reviewers and the release process by writing your own release notes. See below for an example.
-->

[IOS] [BUGFIX] [TextView] - Fix Korean/Chinese/Japanese input for multiline TextView on iOS.

<!--
  **INTERNAL and MINOR tagged notes will not be included in the next version's final release notes.**

    CATEGORY
  [----------]      TYPE
  [ CLI      ] [-------------]    LOCATION
  [ DOCS     ] [ BREAKING    ] [-------------]
  [ GENERAL  ] [ BUGFIX      ] [ {Component} ]
  [ INTERNAL ] [ ENHANCEMENT ] [ {Filename}  ]
  [ IOS      ] [ FEATURE     ] [ {Directory} ]   |-----------|
  [ ANDROID  ] [ MINOR       ] [ {Framework} ] - | {Message} |
  [----------] [-------------] [-------------]   |-----------|

 EXAMPLES:

 [IOS] [BREAKING] [FlatList] - Change a thing that breaks other things
 [ANDROID] [BUGFIX] [TextInput] - Did a thing to TextInput
 [CLI] [FEATURE] [local-cli/info/info.js] - CLI easier to do things with
 [DOCS] [BUGFIX] [GettingStarted.md] - Accidentally a thing/word
 [GENERAL] [ENHANCEMENT] [Yoga] - Added new yoga thing/position
 [INTERNAL] [FEATURE] [./scripts] - Added thing to script that nobody will see
-->
Pull Request resolved: #19809

Differential Revision: D13326614

Pulled By: shergin

fbshipit-source-id: 6a5cab3f7290f0f623a6f4c29353a573eb321b0b
facebook-github-bot pushed a commit that referenced this issue Feb 4, 2019
Summary:
Follow-up to #19809

This fix generalizes the `setAttributedString:` fix to single-line text fields.

Fixes #19339

_Pull requests that expand test coverage are more likely to get reviewed. Add a test case whenever possible!_
Pull Request resolved: #22546

Differential Revision: D13948951

Pulled By: shergin

fbshipit-source-id: 67992c02b32f33f6d61fac4554e4f46b973262c1
matt-oakes pushed a commit to matt-oakes/react-native that referenced this issue Feb 7, 2019
…#22546)

Summary:
Follow-up to facebook#19809

This fix generalizes the `setAttributedString:` fix to single-line text fields.

Fixes facebook#19339

_Pull requests that expand test coverage are more likely to get reviewed. Add a test case whenever possible!_
Pull Request resolved: facebook#22546

Differential Revision: D13948951

Pulled By: shergin

fbshipit-source-id: 67992c02b32f33f6d61fac4554e4f46b973262c1
t-nanava pushed a commit to microsoft/react-native-macos that referenced this issue Jun 17, 2019
…facebook#19809)

Summary:
iOS-specific.
For languages with complex input (such as Japanese or Chinese), a user has to type multiple characters that are then merged into a single one.
If `-[UITextView setAttributedString:]` is used while the user is still typing, it resets the input and characters are not being treated as typed together.

This PR avoids calling this method if possible, replacing it by just copying the attributes if the string has not been changed. That preserves the state and user can continue to type Korean or Chinese characters.

Fixes facebook#19339

<!--
  Required: Write your motivation here.
  If this PR fixes an issue, type "Fixes #issueNumber" to automatically close the issue when the PR is merged.
-->

<!--
  Required: Write your test plan here. If you changed any code, please provide us with
  clear instructions on how you verified your changes work. Bonus points for screenshots and videos!
-->

Essentially, the steps to reproduce are described in [the issue](facebook#19339):

1. Type some Korean characters in TextInput, such as "하늘" (buttons `ㅎ`,`ㅏ`,`ㄴ`,`ㅡ`,`ㄹ`).
2. Then move the cursor to the beginning of the text, type "파란" (buttons `ㅍ`,`ㅏ`,`ㄹ`,`ㅏ`,`ㄴ`) this time.

**Behaviour before this fix (broken)**
Actual text: `ㅍㅏㄹㅏㄴ하늘`.
Expected text: `파란하늘`.
Characters aren't combined properly.

![ezgif com-resize](https://user-images.githubusercontent.com/466427/41613572-4256dda8-73f6-11e8-99a9-0ab833202b95.gif)

**Behaviour after this fix (correct)**
Actual text: `파란하늘`.
Expected text: `파란하늘`.
Characters are combined, the same behaviour is in vanilla iOS `UITextView`.

![input-with-fix](https://user-images.githubusercontent.com/466427/41613526-1aae2284-73f6-11e8-87f2-c1cef51cd83a.gif)

<!--
  Does this PR require a documentation change?
  Create a PR at https://github.com/facebook/react-native-website and add a link to it here.
-->

<!--
  Required.
  Help reviewers and the release process by writing your own release notes. See below for an example.
-->

[IOS] [BUGFIX] [TextView] - Fix Korean/Chinese/Japanese input for multiline TextView on iOS.

<!--
  **INTERNAL and MINOR tagged notes will not be included in the next version's final release notes.**

    CATEGORY
  [----------]      TYPE
  [ CLI      ] [-------------]    LOCATION
  [ DOCS     ] [ BREAKING    ] [-------------]
  [ GENERAL  ] [ BUGFIX      ] [ {Component} ]
  [ INTERNAL ] [ ENHANCEMENT ] [ {Filename}  ]
  [ IOS      ] [ FEATURE     ] [ {Directory} ]   |-----------|
  [ ANDROID  ] [ MINOR       ] [ {Framework} ] - | {Message} |
  [----------] [-------------] [-------------]   |-----------|

 EXAMPLES:

 [IOS] [BREAKING] [FlatList] - Change a thing that breaks other things
 [ANDROID] [BUGFIX] [TextInput] - Did a thing to TextInput
 [CLI] [FEATURE] [local-cli/info/info.js] - CLI easier to do things with
 [DOCS] [BUGFIX] [GettingStarted.md] - Accidentally a thing/word
 [GENERAL] [ENHANCEMENT] [Yoga] - Added new yoga thing/position
 [INTERNAL] [FEATURE] [./scripts] - Added thing to script that nobody will see
-->
Pull Request resolved: facebook#19809

Differential Revision: D13326614

Pulled By: shergin

fbshipit-source-id: 6a5cab3f7290f0f623a6f4c29353a573eb321b0b
@facebook facebook locked as resolved and limited conversation to collaborators Dec 4, 2019
@react-native-bot react-native-bot added the Resolution: Locked This issue was locked by the bot. label Dec 4, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Impact: Regression Describes a behavior that used to work on a prior release, but stopped working recently. Platform: iOS iOS applications. Resolution: Locked This issue was locked by the bot.
Projects
None yet
10 participants