我正在尝试分别管理2个输入的状态。这2个输入具有浮动标签动画。当您专注于输入时,占位符会移到顶部,而onBlur会返回到其原始位置。
现在,我有一个名为handleFocusAndBlur
的函数,需要在其中实现该逻辑。现在,此行为有点奇怪,因为即使在一个输入中仅包含文本,如果您转到空输入,则已填写的输入的标签也将返回其原始位置,而不是那样。>
这是我正在使用的组件:
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { View, TextInput, Animated } from 'react-native';
import styles from '../../styles/SigningScreenStyles';
export default class SigningInputs extends Component {
state = { isFocused: false };
componentWillMount() {
this.animatedIsFocused = new Animated.Value(0);
}
componentDidUpdate() {
const { isFocused } = this.state;
Animated.timing(this.animatedIsFocused, {
toValue: isFocused ? 1 : 0,
duration: 200,
}).start();
}
// SEE THIS FUNCTION
handleFocusAndBlur = () => {
const { usernameLength, passwordLength } = this.props;
if (usernameLength || passwordLength) {
this.setState({ isFocused: false });
} else {
this.setState({ isFocused: true });
}
};
render() {
const { secureTextEntry, onChangeText, labelText } = this.props;
const labelStyle = {
position: 'absolute',
left: 0,
top: this.animatedIsFocused.interpolate({
inputRange: [0, 1],
outputRange: [10, -10],
}),
fontSize: this.animatedIsFocused.interpolate({
inputRange: [0, 1],
outputRange: [25, 14],
}),
color: this.animatedIsFocused.interpolate({
inputRange: [0, 1],
outputRange: ['black', 'gray'],
}),
};
return (
<>
<View style={styles.inputContainer}>
<Animated.Text style={labelStyle}>{labelText}</Animated.Text>
<TextInput
style={styles.inputs}
onChangeText={onChangeText}
onFocus={this.handleFocusAndBlur}
onBlur={this.handleFocusAndBlur}
blurOnSubmit
secureTextEntry={secureTextEntry}
propsLength
/>
</View>
</>
);
}
}
SigningInputs.defaultProps = {
secureTextEntry: false,
};
SigningInputs.propTypes = {
secureTextEntry: PropTypes.oneOfType([PropTypes.bool]),
onChangeText: PropTypes.func.isRequired,
labelText: PropTypes.oneOfType([PropTypes.string]).isRequired,
usernameLength: PropTypes.oneOfType([PropTypes.string, PropTypes.number])
.isRequired,
passwordLength: PropTypes.oneOfType([PropTypes.string, PropTypes.number])
.isRequired,
};
这就是我调用该组件的方式:
const { username, password } = this.state;
<SigningInputs
onChangeText={user => this.setState({ username: user })}
labelText="User Name"
usernameLength={username.length}
/>
<SigningInputs
onChangeText={pass => this.setState({ password: pass })}
secureTextEntry
labelText="Password"
passwordLength={password.length}
/>
当我只有一个输入时,这很容易,但是现在有了2个输入,我发现我需要实现更多的逻辑。
有机会有人看吗?
答案 0 :(得分:2)
更新:您的handleFocusAndBlur
逻辑存在一些缺陷,请考虑以下情况:您集中精力,handleFocusAndBlur
将isFocused
设置为true,标签会移动。现在您键入,失去焦点,现在handleFocusAndBlur
将isFocused
设置为false。因此标签再次移动。应该没有,因为有文字。
如果完全删除isFocused
状态,则可以解决此问题。因为您不需要知道它是否专注,所以有两个单独的回调。
添加单独的处理程序以进行聚焦和模糊处理(正如乔纳森·欧文的回答所暗示的那样)
<TextInput
style={styles.inputs}
onChangeText={onChangeText}
onFocus={this.handleFocus}
onBlur={this.handleBlur}
blurOnSubmit
secureTextEntry={secureTextEntry}
propsLength
/>
handleFocus = () => {
const { inputLength } = this.props;
if (!inputLength) {
Animated.timing(this.animatedIsFocused, {
toValue: 1,
duration: 200
}).start()
}
}
handleBlur = () => {
const { inputLength } = this.props;
if (!inputLength) {
Animated.timing(this.animatedIsFocused, {
toValue: 0,
duration: 200
}).start()
}
}
您可以将长度作为通用道具inputLength
发送:
const { username, password } = this.state;
<SigningInputs
onChangeText={user => this.setState({ username: user })}
labelText="User Name"
inputLength={username.length}
/>
<SigningInputs
onChangeText={pass => this.setState({ password: pass })}
secureTextEntry
labelText="Password"
inputLength={password.length}
/>
答案 1 :(得分:2)
分割手柄焦点和模糊效果有效
handleFocus = () => {
const {length} = this.props
if (!length) {
Animated.timing(this.animatedIsFocused, {
toValue: 1,
duration: 200
}).start()
}
}
handleBlur = () => {
const {length} = this.props
if (!length) {
Animated.timing(this.animatedIsFocused, {
toValue: 0,
duration: 200
}).start()
}
}
还删除componentDidUpdate函数,更新您的输入onFocus和onBlur并仅传递一次长度道具(如另一个答案中所述)