我构建了反应原生应用程序。我创建了 pintInput 组件,该组件根据我在 props 中传递的输入数量创建动态文本输入。
我正在尝试使文本输入的颜色占位符发生变化,当它被遮挡时它是黑色的,否则当它模糊时是红色的。
我将占位符文本颜色绑定到"侦听"状态更改。 当它打开焦点时,我将状态设置为 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>
);
}
}
状态渲染保存的JSX,你的文本输入永远不会被重新渲染,因为你只在componentDidMount
中调用_createDinamicallyInputs
。
如果你想让你的文本输入被重新渲染,你必须调用一个函数,在组件的渲染方法中生成它们(修改_createDinamicallyInputs
(。像这样:
render() {
return (
<View style={container}>
<View style={textViewStyle}>
{this._createDinamicallyInputs()}
</View>
其中_createDinamicallyInputs
应返回文本输入列表,而不是将列表保存在状态中。
编辑:这是可以做到的一种方法:
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>
);
}
}