我创建了一个名为inputText.js
的组件,该组件用于根据需要声明一个特定的输入字段。
我在login.js
内部使用它,并将其作为redux-form
的野外道具传递。
当我开始写得很慢的时候开始出现问题,如果我开始写得更快,我就会变得不耐烦,我在该字段中最后写的文本与已经写的文本混合在一起,并且在中间,甚至是指示焦点位于单词内部的竖版也位于写作中间。
链接:Expo
代码:inputText.js
import PropTypes from 'prop-types';
import React, { Component } from 'react';
import { StyleSheet, View } from 'react-native';
import { TextInput, IconButton, Colors } from 'react-native-paper';
import Icon from 'react-native-vector-icons/MaterialIcons';
const propTypes = {
mapElement: PropTypes.func,
onSubmitEditing: PropTypes.func,
onChangeText: PropTypes.func,
value: PropTypes.string,
placeholder: PropTypes.string,
maxLength: PropTypes.number,
keyboardType: PropTypes.string,
secureTextEntry: PropTypes.bool,
label: PropTypes.string,
};
const defaultProps = {
mapElement: n => {},
onSubmitEditing: () => {},
onChangeText: () => {},
value: '',
placeholder: '',
maxLength: 200,
keyboardType: 'default',
secureTextEntry: false,
label: '',
};
const styles = StyleSheet.create({
inputBox: {
width: 300,
//backgroundColor: 'rgba(255, 255,255,0.2)',
//borderRadius: 25,
//paddingHorizontal: 16,
//fontSize: 16,
//color: '#ffffff',
//marginVertical: 10,
},
icon: {
position: 'absolute',
top: 20,
right: 10,
},
});
class InputText extends Component<{}> {
constructor(props) {
super(props);
this.state = {
vPwd: props.secureTextEntry,
};
}
changePwdType = () => {
this.setState(prevState => ({
vPwd: !prevState.vPwd,
}));
};
render() {
const {
label,
placeholder,
secureTextEntry,
iconPassword,
keyboardType,
maxLength,
value,
onChangeText,
onSubmitEditing,
} = this.props;
const { vPwd } = this.state;
let icEye = vPwd ? 'visibility-off' : 'visibility';
return (
<View>
<TextInput
style={styles.inputBox}
placeholder={placeholder}
secureTextEntry={vPwd}
keyboardType={keyboardType}
maxLength={maxLength}
returnKeyType="next"
value={value}
onSubmitEditing={onSubmitEditing}
onChangeText={onChangeText}
label={label}
underlineColor="#fff"
theme={{
colors: {
primary: '#f5a442',
background: 'transparent',
placeholder: '#fff',
},
}}
/>
{secureTextEntry && iconPassword && (
<Icon
style={styles.icon}
name={icEye}
size={25}
onPress={this.changePwdType}
/>
)}
</View>
);
}
}
InputText.defaultProps = defaultProps;
InputText.propTypes = propTypes;
export default InputText;
代码:login.js
import React, { Component } from 'react';
import { StyleSheet, View, Text, TouchableOpacity } from 'react-native';
import { Field, reduxForm } from 'redux-form';
import { HelperText } from 'react-native-paper';
import Logo from '../components/Logo';
import Form from '../components/Form';
import InputText from '../components/InputText';
import { Actions } from 'react-native-router-flux';
class Login extends Component<{}> {
signup() {
Actions.signup();
}
onSubmit = values => {
console.log(values);
};
renderTextInput = field => {
const {
meta: { touched, error },
label,
secureTextEntry,
iconPassword,
maxLength,
keyboardType,
placeholder,
input: { onChange, ...restInput },
} = field;
return (
<View>
<InputText
onChangeText={onChange}
maxLength={maxLength}
placeholder={placeholder}
keyboardType={keyboardType}
secureTextEntry={secureTextEntry}
iconPassword={iconPassword}
label={label}
{...restInput}
/>
{touched && error && (
<HelperText type="error" visible={true}>
{error}
</HelperText>
)}
</View>
);
};
render() {
const { handleSubmit } = this.props;
return (
<View style={styles.container}>
<Logo />
<View style={styles.inputContainerStyle}>
<Field
name="email"
label="Email"
placeholder="Email@host.com"
component={this.renderTextInput}
/>
<Field
name="password"
label="Password"
placeholder="***********"
secureTextEntry={true}
iconPassword={true}
component={this.renderTextInput}
/>
</View>
<TouchableOpacity
style={styles.button}
onPress={handleSubmit(this.onSubmit)}>
<Text style={styles.buttonText}>Login</Text>
</TouchableOpacity>
<View style={styles.signupTextCont}>
<Text style={styles.signupText}>Do not have an account yet?</Text>
<TouchableOpacity>
<Text style={styles.signupButton}> Signup</Text>
</TouchableOpacity>
</View>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
backgroundColor: '#455a64',
flex: 1,
alignItems: 'center',
justifyContent: 'center',
},
signupTextCont: {
flexGrow: 1,
alignItems: 'flex-end',
justifyContent: 'center',
paddingVertical: 16,
flexDirection: 'row',
},
signupText: {
color: 'rgba(255,255,255,0.6)',
fontSize: 16,
},
signupButton: {
color: '#ffffff',
fontSize: 16,
fontWeight: '500',
},
button: {
width: 300,
backgroundColor: '#1c313a',
borderRadius: 25,
marginVertical: 10,
paddingVertical: 13,
},
buttonText: {
fontSize: 16,
fontWeight: '500',
color: '#ffffff',
textAlign: 'center',
},
inputContainerStyle: {
backgroundColor: 'rgba(255, 255, 255, 0.15)',
padding: 5,
paddingBottom: 10,
borderRadius: 5,
},
});
const validate = values => {
const errors = {};
if (!values.email) {
errors.email = 'Email is required';
}
if (!values.password) {
errors.password = 'Password is required';
}
return errors;
};
export default reduxForm({
form: 'login',
validate,
})(Login);