【问题标题】:react native change placeholder to textInput dynamically动态反应原生更改占位符到 textInput
【发布时间】:2018-04-22 05:04:18
【问题描述】:

我构建反应原生应用程序。 我创建了 pintInput 组件,该组件根据我在 props 中传递的输入数量动态创建 textInput。

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

我将 placeholderTextColor 绑定到“监听”状态更改。当它 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>
        );
    }



}

【问题讨论】:

    标签: react-native


    【解决方案1】:

    您从状态渲染保存的 JSX,并且您的 TextInputs 永远不会重新渲染,因为您仅在 componentDidMount 中调用 _createDinamicallyInputs

    如果你希望你的 TextInputs 被重新渲染,你必须在组件的 render 方法中调用一个生成它们的函数(修改 _createDinamicallyInputs)。像这样的:

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

    _createDinamicallyInputs 应该返回一个 TextInputs 列表,而不是将列表保存在 state 中。

    编辑:这是可以做到的一种方法:

    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>
          );
      }
    
    
    
    }
    

    【讨论】:

    • 这样我得到错误“E:\Projects\moonsite\glassify-mobile\node_modules\react-native\Libraries\Core\ExceptionsManager.js:73 警告:在现有状态转换期间无法更新(例如在 render 或其他组件的构造函数中)。渲染方法应该是 props 和 state 的纯函数;构造函数的副作用是反模式,但可以移动到 componentWillMount"
    • 是的,需要修改_createDinamicallyInputs,还有其他一些函数,我只是指出你做错了什么。
    • 好的,你知道有什么问题吗?我可以改变什么才能让它起作用?
    • 看起来不错,但会抛出错误“null 不是对象(评估 this.temText[index-1].myRef.blur)。this.error 位于 pinInput index.js:151
    • 你有什么解决办法吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-02-06
    • 2020-11-28
    • 1970-01-01
    • 2015-12-31
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多