将原生更改占位符动态地反应到textInput

时间:2017-11-09 09:12:01

标签: react-native

我构建反应本机应用程序。 我创建了pintInput组件,它通过在props中传递的输入数量动态地创建textInput。

我正在尝试使文本输入的颜色占位符发生变化,当它变暗时它会变成黑色,当它模糊时会变成红色。

我将placeholderTextColor绑定到“listen”状态更改。当它onFocus时,我将状态设置为true,其他为false。

但我仍然没有工作,因为它不听取改变。它向我显示所有这些都是红色。

    import React, { Component } from 'react';
import {
    View,
    TextInput,
    Platform,
    Text
} from 'react-native';

import Input from '../Input';

// import styles
import { globalStyle } from '../../../../assets/styles/globalStyle';
import { style } from './style';



export default class PinInput extends Component {

    constructor(props) {

        super(props);
        this.state = {
            value: '',
            valid: false,
            errMsg: '',
            styleUnder:false,

        }
        this._onChangeText = this._onChangeText.bind(this);
        this.temText = [];
    }

    componentDidMount() {
        this._createDinamicallyInputs();
    }
    _onFocus(){
        console.log("focus");
        this.setState({styleUnder:true})
    }
    _onBlur(){
        console.log("blur");
        console.log(this);
        this.setState({styleUnder:false})
    }
    _createDinamicallyInputs() {
        for (var i = 0; i < this.props.numOfInputs; i++) {
            this.temText.push(i);
        }
        const { container, pinInputStyle,pinInputStyle2 } = style;
        const {styleUnder} = this.state;
        var indet = this.temText.map((i) => {
            return (
                <TextInput
                    ref={ref => this.temText[i] = { myRef: ref, next: i + 1 }}
                    type={'TextInput'}
                    underlineColorAndroid={'transparent'}
                    autoCapitalize={'none'}
                    autoCorrect={false}
                    onChangeText={(value) => this._onChangeText(value)}
                    placeholder={this.props.placeholder}
                    keyboardType={Platform.OS === 'ios' ? 'number-pad' : 'numeric'}
                    autoFocus={i === 0}
                    maxLength={1}
                    key={i}
                    onFocus={()=>this._onFocus()}
                    onBlur = {()=>this._onBlur()}
                    placeholderTextColor ={ this.state.styleUnder ? "black" : "red"}
                    //onEndEditing = { this.verifyCode.bind(this) }
                    enablesReturnKeyAutomatically={false}
                    style={[pinInputStyle]}
                />
            )
        });
        console.log(this.temText);
        this.setState({ textInputsDinamic: indet })
    }

    _onChangeText(value) {
        var tempState = this.state.value + value;
        this.setState({ ...this.state, value: tempState},()=>{
            console.log(this.state.value)
            this._checkValue();
        });

        // this.props.onVerify(value);    

    }
    _checkValue() {
        var index = this.state.value.length;
        if (this.temText[index-1].next >= this.props.numOfInputs) {
            this.temText[index-1].myRef.blur()
            if (this.state.value == this.props.code) {
                this.setState({ errMsg: 'good code!' });
            }
            else {
                this.setState({ errMsg: 'wrong code!' })
                this._resetPinInputs();

            }
        }
        else {
            this.temText[index-1].myRef.blur()
            this.temText[index].myRef.focus()
        }
    }

    _resetPinInputs(){
        this.temText.map(input=>{
            input.myRef.clear();
        })
        this.temText[0].myRef.focus();
        this.setState({value:''})
    }

    _showErrorMsg() {
        return (
            <Text>{this.state.errMsg}</Text>
        )
    }
    render() {
        const { container, pinInputStyle, codeStyle, textViewStyle } = style;
        return (
            <View style={container}>
                <View style={textViewStyle}>
                    {this.state.textInputsDinamic}
                </View>
                <View style={textViewStyle}>
                    {this.state.errMsg ? this._showErrorMsg() : null}
                </View>


            </View>
        );
    }



}

1 个答案:

答案 0 :(得分:2)

您从状态渲染已保存的JSX,并且您的TextInput不会被重新渲染,因为您只在_createDinamicallyInputs中调用componentDidMount

如果希望重新呈现TextInputs,则必须在组件的render方法中调用生成它们的函数(已修改_createDinamicallyInputs)。像这样:

render() {
    return (
        <View style={container}>
            <View style={textViewStyle}>
                {this._createDinamicallyInputs()}
            </View>

其中_createDinamicallyInputs应返回TextInputs列表,而不是将列表保存为状态。

编辑:这是一种可行的方式:

import React, { Component } from 'react';
import {
  View,
  TextInput,
  Platform,
  Text
} from 'react-native';

import Input from '../Input';

// import styles
import { globalStyle } from '../../../../assets/styles/globalStyle';
import { style } from './style';

export default class PinInput extends Component {

  constructor(props) {

      super(props);
      this.state = {
          value: '',
          valid: false,
          errMsg: '',
          styleUnder: [],

      }
      this._onChangeText = this._onChangeText.bind(this);
      this.temText = [];
  }

  componentDidMount() {
      for (var i = 0; i < this.props.numOfInputs; i++) {
          this.temText.push(i);
      }

      this.setState({ styleUnder: this.temText.map((item) => false) })
  }

  _onFocus(index){
      console.log(index);
      this.setState({ styleUnder: this.temText.map((i, j) => {
          if(j === index)
            return true;

          return false;
      })  })
  }
  _onBlur(index){
      console.log(index);
  }
  _createDinamicallyInputs() {
      const { container, pinInputStyle,pinInputStyle2 } = style;
      const {styleUnder} = this.state;
      return this.temText.map((i, index) =>
              <TextInput
                  ref={ref => this.temText[i] = { myRef: ref, next: i + 1 }}
                  type={'TextInput'}
                  underlineColorAndroid={'transparent'}
                  autoCapitalize={'none'}
                  autoCorrect={false}
                  onChangeText={(value) => this._onChangeText(value)}
                  placeholder={this.props.placeholder}
                  keyboardType={Platform.OS === 'ios' ? 'number-pad' : 'numeric'}
                  autoFocus={i === 0}
                  maxLength={1}
                  key={index}
                  onFocus={()=>this._onFocus(index)}
                  onBlur = {()=>this._onBlur(index)}
                  placeholderTextColor ={ this.state.styleUnder[index] ? "black" : "red"}
                  //onEndEditing = { this.verifyCode.bind(this) }
                  enablesReturnKeyAutomatically={false}
                  style={[pinInputStyle]}
              />
          )
  }

  _onChangeText(value) {
      var tempState = this.state.value + value;
      this.setState({ ...this.state, value: tempState},()=>{
          console.log(this.state.value)
          this._checkValue();
      });

      // this.props.onVerify(value);

  }
  _checkValue() {
      var index = this.state.value.length;
      if (this.temText[index-1].next >= this.props.numOfInputs) {
          this.temText[index-1].myRef.blur()
          if (this.state.value == this.props.code) {
              this.setState({ errMsg: 'good code!' });
          }
          else {
              this.setState({ errMsg: 'wrong code!' })
              this._resetPinInputs();

          }
      }
      else {
          this.temText[index-1].myRef.blur()
          this.temText[index].myRef.focus()
      }
  }

  _resetPinInputs(){
      this.temText.map(input=>{
          input.myRef.clear();
      })
      this.temText[0].myRef.focus();
      this.setState({value:''})
  }

  _showErrorMsg() {
      return (
          <Text>{this.state.errMsg}</Text>
      )
  }
  render() {
      const { container, pinInputStyle, codeStyle, textViewStyle } = style;

      return (
          <View style={container}>
              <View style={textViewStyle}>
                {this._createDinamicallyInputs()}
              </View>
              <View style={textViewStyle}>
                  {this.state.errMsg ? this._showErrorMsg() : null}
              </View>


          </View>
      );
  }



}