TextInput忽略React Native上的双击(句点)

时间:2018-05-08 20:31:28

标签: reactjs react-native textinput

我有TextInput组件,它会在用户输入时更改状态,但我意识到由于TextInput的值使用this.state.text作为值,双击空间不会在iO上产生句点。

是否有解决这个问题的方法,因此对空间进行双击还是可以在ios上产生一段时间?

 onChange =(text) => {
    this.setState({text});
 }




<TextInput
          onChangeText={this.onChange}
          onSubmitEditing={this.onSubmit}
          value={this.state.text}
          autoCapitalize="sentences"
          blurOnSubmit={false}
          editable={true}
        />

3 个答案:

答案 0 :(得分:1)

textInput字段上的

onChange事件会导致问题,例如键盘快捷键(双击空格以创建句点(。)),因为每次击键都会改变状态,键盘无法捕捉双打空间。

因此,不是将值存储在状态中,而是将其捕获到onSubmitEditing,捕获最终值。

   <TextInput
      onSubmitEditing={this.onSubmit}
      value={this.state.text}
      placeholder="Say Something.."
      blurOnSubmit={false}
      editable={true}
    />

然后我们创建一个提交函数,该函数对文本执行某些操作并清除该字段。

  onSubmit = (e) => {

    const text = e.nativeEvent.text;

    this.setState({text}, () => { // <- Important Callback after setstate

          //Whatever U want to do with the data here.

          this.setState({text: ''}) // clear the field (this must be in the callback)

    })
  }
  

我们将this.state.text设置为文本,以便我们可以将其设置回&#39;&#39;后   打回来。如果你不做这一步,状态就不会改变,而且   组件没有用空字段刷新。

我意识到使用这种方法,所有键盘功能都可以正常工作,包括句点(。)的双倍空格,甚至复制和粘贴值,而不使用setState。

更新:启用多行解决方案。

以上适用于单行,对于我们不使用onSubmitEditing并使用按钮的多行,我们需要在文本输入中添加引用。

    <TextInput
      ref={input => { this.textMessage = input }} //Important.
      //onSubmitEditing={this.onSubmit} //Remove so we can use newline
      value={this.state.text}
      placeholder="Say Something.."
      blurOnSubmit={false}
      editable={true}
      multiline={true}
    />

创建一个执行提交的按钮

<Button onPress={this.onSubmit} 
  title="Send"
/>

通过onSubmit函数的引用获取值的方法不同

  onSubmit = () => {

    const text = this.textMessage._lastNativeText.trim(); //Remember the ref from textInput?
    this.setState({text}, () => {
       //Do whatever u want with the text here
       this.setState({text: ''}) //clear the field
       this.textMessage._lastNativeText = ''; //you need to clear this too
    })
  

注意:如果你没有将this.textMessage._lastNativeText设置为空,那么你   单击“发送”时将继续提交上一个值   即使textInput在视觉上看起来是空的。

答案 1 :(得分:0)

import React, { Component } from 'react';
import { AppRegistry, TouchableOpacity, View, TextInput } from 'react-native';

class UselessTextInput extends Component {
    constructor(props) {
        super(props)
        this.state = {
            lastPress: 0
        }
    }

    onPress = () => {
        var delta = new Date().getTime() - this.state.lastPress;

        if (delta < 200) {
            alert("DOUBLE TAP")
            // double tap happend
        }

        this.setState({
            lastPress: new Date().getTime()
        })
    }

    render() {
        return (
            <TouchableOpacity onPress={this.onPress}>
                <TextInput
                    pointerEvents="none"
                />
            </TouchableOpacity>
        );
    }
}

export default class UselessTextInputMultiline extends Component {
    constructor(props) {
        super(props);
        this.state = {
            text: 'Useless Multiline Placeholder',
        };
    }

    // If you type something in the text box that is a color, the background will change to that
    // color.
    render() {
        return (
            <View style={{
                backgroundColor: this.state.text,
                borderBottomColor: '#000000',
                borderBottomWidth: 1
            }}
            >
                <UselessTextInput
                    multiline={true}
                    numberOfLines={4}
                    onChangeText={(text) => this.setState({ text })}
                    value={this.state.text}
                />
            </View>
        );
    }
}

// skip these lines if using Create React Native App
AppRegistry.registerComponent(
    'AwesomeProject',
    () => UselessTextInputMultiline
);

您可以根据自己的要求对其进行编辑我已经在原生文档网站上做了反应并且有效。

答案 2 :(得分:0)

这与苹果的行为非常接近。如果有人能找到一种与苹果不具有同等功能的方法,请告诉我。

import {useRef} from "react";

const useTextInputReplacer = () => {
  const lastText = useRef<string>("");
  const lastSpaceEnteredAt = useRef<number>();
  const periodReplaceDisabled = useRef<boolean>(true);

  const isLastCharacterAlphaNumeric = str => str[str.length - 1].match(/[a-zA-Z0-9]/);

  return (_text) => {
    if (lastText.current && _text.length) {
      if (lastText.current.length < _text.length) {  // add case
        if (_text[_text.length - 1] === " " && !periodReplaceDisabled.current) {
          const now = new Date().getTime();
          if (lastSpaceEnteredAt.current && (now - lastSpaceEnteredAt.current) < 300) {
            lastSpaceEnteredAt.current = undefined;
            _text = _text.replace(/\s{2}$/, ". ");
            periodReplaceDisabled.current = true;
          } else if (!periodReplaceDisabled.current && isLastCharacterAlphaNumeric(lastText.current)) {
            lastSpaceEnteredAt.current = now;
          }
        } else {
          periodReplaceDisabled.current = !isLastCharacterAlphaNumeric(lastText.current);
        }
      } else if (lastText.current.length > _text.length) { // deletion case
        periodReplaceDisabled.current = lastText.current[lastText.current.length - 1] === "." || !isLastCharacterAlphaNumeric(_text);
      }
    }
    lastText.current = _text;
    return _text;
  };
};

然后在您的组件中


  const textInputReplacer = useTextInputReplacer();

<Input 
   onChangeText={text => updateText(textInputReplacer(text))}
/>