1. 程式人生 > >記一次 react-naitve TextInput 的一些坑

記一次 react-naitve TextInput 的一些坑

業務場景描述:

 


 

話不多說,直接上程式碼 關於 TextInput 輸入框在什麼時候清空文字內容

/** react 組建的引用 */
import React, {Component} from "react";
import {
  StyleSheet, Text, View, TextInput, Dimensions,Platform
} from "react-native";

const {width, height} = Dimensions.get('window');//螢幕寬度
export default class Vue2 extends Component {
  constructor(props) {
    super(props);
    this.state = {
      inputValue: ''
    };
  }

  render() {
    return (
      <View style={styles.container}>
        <TextInput
          ref={ref => this._textInstance = ref} // 獲取TextInput例項
          placeholder={"手機驗證碼!!!!!!"}
          style={{width: width, height: 40, borderWidth: 1}}
          onChangeText={(value) => {
            console.log(1111, '------onChangeText', value)
            this.state.inputValue = value  // 只是簡單的賦值操作,頁面不更新
          }}
          onEndEditing={() => {
            console.log(1111, '++++++++onEndEditing', this.state.inputValue)
            (Platform.OS === 'ios') && this.setState({inputValue: this.state.inputValue});
          }}
          value={this.state.inputValue}
        />

        <Text style={{fontSize: 20, marginTop: 30}} onPress={() => {
          this.setState({inputValue: ''})
        }
        }>{'點我清空輸入'}</Text>
      </View>
    );
  }
}
const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
  }
});

react-naitve 官網 https://reactnative.cn/docs/0.56/textinput/#onendediting 對TextInput  value 屬性的描述如下:

TextInput是一個受約束的(Controlled)的元件,意味著如果提供了value屬性,原生值會被強制與value屬性保持一致

如上程式碼,只是單純的賦值操作,不通過 setState() 方法重新渲染頁面,清空方法時無效的,此時此刻 TextInput 中 value 繫結的 inputValue 依然是原生的 value ,因為預設一開始 我們的賦值 this.state.inputValue = '' 相當於沒有提供 value 的值, 所以導致 原生的沒有保持一致,點選清空按鈕,無法清空輸入。

onChangeText 的坑:

ios (列印結果如圖) :

每一次鍵盤的輸入都是一次 onChangeText 事件

android (列印結果) :

只有在最後一步等你確定好了輸入結果,才執行 onChangeText 事件

因為兩種事件執行的 時機不同,就會讓我們調入深坑而無法自拔
如果你的程式碼和上面一樣,在輸入英文和數字的時候,老鐵沒毛病,默默地感謝一下公司的產品沒有為難你,如果要求輸入的是中文如第一張設計圖(使用者名稱,手機號,身份證號的強強驗證)當你輸入中文的時候就傻逼了

android 手機一切 ok 因為 onChangeText 事件只在最後一次執行,但是 ios 手機你會發現怎麼也無法輸入中文(因為每一次的state的都是去當前的輸入值啊親,而且每一次都 setState, 你說坑爹不肯爹 ),但是各位 可愛的 攻城獅萌不要害怕,在程式的世界裡沒有程式解決不了的問題(就看時間夠不夠久對吧!!!)。

既然已經知道為啥了,分析出了原因,解決問題也是分分鐘的事情啦!!!只要判斷一下手機型號就 ok 啦,解決問題之前我再介紹一下另外一個 屬性  onEndEditing  顧名思義 當文字輸入結束後呼叫此回撥函式。

結合著兩個屬性就可完美的解決輸入中文以及清除輸入內容的問題啦
完整程式碼如下,各位看官,拿走不謝(後期會分享更多的乾貨)
 

import React, {Component} from "react";
import {
  StyleSheet, Text, View, TextInput, Dimensions,Platform
} from "react-native";

const {width, height} = Dimensions.get('window');//螢幕寬度
export default class Vue2 extends Component {
  constructor(props) {
    super(props);
    this.state = {
      inputValue: ''
    };
  }

  render() {
    return (
      <View style={styles.container}>
        <TextInput
          ref={ref => this._textInstance = ref} // 獲取TextInput例項
          placeholder={"手機驗證碼!!!!!!"}
          style={{width: width, height: 40, borderWidth: 1}}
          onChangeText={(value) => {
            console.log(1111, '------onChangeText', value)
            this.state.inputValue = value  // 這裡的賦值,為了 onEndEditing 取值
            !(Platform.OS === 'ios') && this.setState({inputValue: value})
          }}
          onEndEditing={() => {
            console.log(1111, '++++++++onEndEditing', this.state.inputValue)
            (Platform.OS === 'ios') && this.setState({inputValue: this.state.inputValue});
          }}
          value={this.state.inputValue}
        />

        <Text style={{fontSize: 20, marginTop: 30}} onPress={() => {
          this.setState({inputValue: ''})
        }
        }>{'點我清空輸入'}</Text>
      </View>
    );
  }
}
const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
  }
});

更多的乾貨請點選這裡 https://blog.csdn.net/woleigequshawanyier

react-native 實戰專案學習 https://github.com/15826954460/BXStage

歡迎各位看官的批評和指正,共同學習和成長

希望該文章對您有幫助,也希望得到您的鼓勵和支援