Skip to content

Conversation

flare216
Copy link

@flare216 flare216 commented Jun 16, 2016

I'm experiencing a issue about input Chinese Pinyin.
I'm using 0.27.2,
I have the following codes:

render(){
    return <TextInput value={this.state.value} onChangeText={(text) => this._onChangeText(text)}/>
}
_onChangeText(text){
    this.setState({value: text});
}

Under the Chinese Pinyin input mode, when i input the first letter, then _onChangeText function invoked,
and then the TextInput value property changed, this lead to a "can't input Chinese" bug.
After seaching about Chinese Piyin input on ios, i fixed this issue in this patch, that is when textinput exist selected text, don't send onChange event.
But i' m not sure if i'm doing the correct thing, as in my another project using 0.25.1 does not produce this issue.

@ghost
Copy link

ghost commented Jun 16, 2016

By analyzing the blame information on this pull request, we identified @nicklockwood and @bnham to be potential reviewers.

@ghost
Copy link

ghost commented Jun 16, 2016

Thank you for your pull request and welcome to our community. We require contributors to sign our Contributor License Agreement, and we don't seem to have you on file. In order for us to review and merge your code, please sign up at https://code.facebook.com/cla - and if you have received this in error or have any questions, please drop us a line at cla@fb.com. Thanks!

@bnham
Copy link
Contributor

bnham commented Jun 16, 2016

Hmm, we've been working on fixing this issue as well. Suppressing the onChangeText callback when there is an active marked text region might be the right way to fix this problem. I'll evaluate this later today.

@flare216
Copy link
Author

@bnham ,you are more thoughtful than I am,maybe there is a better solution.

@bnham
Copy link
Contributor

bnham commented Jun 17, 2016

I tried to repro this using code like this but couldn't repro the bug:

var ControlledTextInput = React.createClass({
  getInitialState: function() {
    return {value: ''};
  },
  _onChangeText: function(text) {
    this.setState({value: text});
  },
  render: function() {
    return <TextInput
      value = {this.state.value}
      style={styles.default}
      multiline={true}
      onChangeText={this._onChangeText.bind(this)}
      />;
  }
});

I can see how this could happen in theory. If [RCTTextView performPendingTextUpdate] ends up calling -[UITextView setAttributedText:] while the marked text range is non-empty, then the call to setAttributedText: would clear the marked text range and break pinyin autocompletion. However, I'm not able to reproduce this in reality, because the call to -performPendingTextUpdate is blocked by the isEqualToString: check here: https://github.com/facebook/react-native/blob/v0.27.1/Libraries/Text/RCTTextView.m#L403

Can you provide more sample code to illustrate the issue?

@flare216
Copy link
Author

@bnham Are you using RN0.27.2 and test it on a real ios(9.3.2) device? I create a new project ,just modificate index.ios.js as follow:

class test extends Component {
  constructor(props){
      super(props);
      this.state = {
        value: ''
      };
  }
  render() {
    return (
      <View style={styles.container}>
        <TextInput
        multiline={true}
        style={styles.input}
        value={this.state.value}
        onChangeText={this._onChangeText.bind(this)}
        />
        <Text style={styles.welcome}>
          Welcome to React Native!
        </Text>
        <Text style={styles.instructions}>
          To get started, edit index.ios.js
        </Text>
        <Text style={styles.instructions}>
          Press Cmd+R to reload,{'\n'}
          Cmd+D or shake for dev menu
        </Text>
      </View>
    );
  }

  _onChangeText(text){
    this.setState({value: text});
  }
}

It reproduced! I made a breakpoint at RTCTextView:403, it not blocked by the isEqualToString.

@bnham
Copy link
Contributor

bnham commented Jun 21, 2016

@flare216, I see the issue now. I wasn't using v0.27.2 so I didn't see the issue originally.

It turns out that this issue is caused by a regression in the way -[RCTTextView setText:] is called in response to the this.setState({value: text}) call. You can read more about the commit that causes this bug in this new issue that I just filed: #8265.

This PR works around the bug that I referenced by ignoring changes when some marked text is present in the view. The idea of not calling back to JS when a marked text range is present is an interesting idea and we might eventually do something like that later. But since we've now traced this bug down to a specific issue in a specific commit, I think it would be better for us to fix the root cause instead of applying a workaround. Therefore I'm going to close out this PR, and you can follow the fix in #8265.

As a temporary workaround, you can downgrade to 0.25.1, which doesn't have this bug.

@bnham bnham closed this Jun 21, 2016
@bnham
Copy link
Contributor

bnham commented Jun 23, 2016

Hi, as I commented in the related issue, this bug was fixed in 26aa27d, which is included in 0.28.0. So you should upgrade to that version.

@dustturtle
Copy link

@bnham how to observer the real change of the text in latest version(I means I need to ignore the marked text change, in search case by Chinese)? I am working on this for a while. I really need some help. @flare216

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants