更改TextInput的值后,无法更改所选文本

pro*_*ojo 6 react-native

我创建了一个示例react-native应用程序。这个程序只包括TextInput和一个按钮

export default class App extends Component {
  state = {
    inputValue: "You can change me!"
  };

  _handleTextChange = inputValue => {
    this.setState({ inputValue });
  };

  _handleSelectionChange = (event) =>{
    this.setState({seleksi : event.nativeEvent.selection});
    console.log(event.nativeEvent.selection);
  }

  _handleButtonPress = () => {
    this.setState({inputValue : "Paijo tenan"});
  };

  render() {
    return (
      <View style={styles.container}>
        <TextInput
          value={this.state.inputValue}
          onChangeText={this._handleTextChange}
          **onSelectionChange={(event)=>this._handleSelectionChange(event)}**
          style={{ width: 200, height:200, padding: 8 }}
          multiline={true}
        />

        <Button
          title="Press me"
          onPress={this._handleButtonPress}
        />
      </View>
    );
  }
}
Run Code Online (Sandbox Code Playgroud)

当我设置onSelectionChange属性时,单击Button之后。TextInput上的文本选择显示异常。

在单击按钮之前,选择显示项目符号的开始和结束

在单击按钮之前,选择显示项目符号的开始和结束

之后,选择不显示项目符号的开始和结束

之后,选择不显示项目符号的开始和结束

但是,当我在TextInput上键入一些文本时,就可以进行选择了。

单击按钮后,如何使选择生效,并在TextInput上使用onSelectionChange道具?为什么会这样呢?如何调试?,我的代码看起来还不错

我在这里https://snack.expo.io/rJ6VxW56x创建博览会小吃

Tra*_*ite 1

我不完全确定这是否是您的意图......但我找到了一个巧妙的解决方法,以确保选择范围与按下按钮后的范围相同。

首先跟踪状态中的选择:

state = {
  inputValue: 'You can change me!',
  selection: {start: 0, end: 0},
};
Run Code Online (Sandbox Code Playgroud)

selection在 TextInput 上使用prop:

selection={this.state.selection}
Run Code Online (Sandbox Code Playgroud)

确保将选择保存到 _handleSelectionChange 中的状态

_handleSelectionChange = (event) => {
  this.setState({ selection: event.nativeEvent.selection });
}
Run Code Online (Sandbox Code Playgroud)

修改 _handleButtonPress 以在更新 inputValue 之前存储选择状态,并使用hackish setTimeout 在文本更改后恢复选择。超时的原因是给 inputValue 时间来更新,这将触发我们想要忽略的 _handleSelectionChange...所以我们在文本更改后将其设置为之前的值,选择范围与之前相同,您会看到可拖动的项目符号。

  _handleButtonPress = () => {
    const selectionBeforeChange = { start: this.state.selection.start, end: this.state.selection.end };
    this.setState({ inputValue : 'Paijo tenan' }, () => {
      setTimeout(() => {
        this.setState({ selection: selectionBeforeChange });
      }, 50);
    });
  };
Run Code Online (Sandbox Code Playgroud)

我真的不喜欢在任何地方使用 setTimeout 但这个解决方案可能会根据您的需求起作用。一个已知的问题是,如果新文本(按下按钮后)短于选择范围,它将无法正确迁移以前的选择。我确信您可以检查新值的长度,并与选择/缩短选择进行比较,以成为有效的选择长度(如果这是您的目标)。

而且,正如用户 Jaws 提到的……最好清楚在何处/何时将函数绑定到此。我喜欢将所有内容绑定在构造函数中,以防止任何不必要的重新绑定/将事物放在一起。

  constructor(props) {
    super(props);
    this._handleButtonPress = this._handleButtonPress.bind(this);
    this._handleSelectionChange = this._handleSelectionChange.bind(this);
    this._handleTextChange = this._handleTextChange.bind(this);
  }
Run Code Online (Sandbox Code Playgroud)