【问题标题】:Can't seem to focus the next TextInput (React-Native)似乎无法关注下一个 TextInput (React-Native)
【发布时间】:2020-03-23 07:00:24
【问题描述】:

我对 React 有一点经验,但仍在尝试了解 React-Native。我正在做一个小项目,我正在做一个登录表单。我想拥有它,这样当您在键盘上按下一步时,它会移动到下一个输入字段。我制作了一个自定义 TextInput 组件,因为我将在几个不同的地方使用它。

import React, { Component } from 'react';
import { Animated, TextInput, View } from 'react-native';
import { Easing } from 'react-native-reanimated';
import { primaryColor, whiteColor } from '../../../../assets/theme';

class FloatingLabelInput extends Component {
    constructor(props) {
        super(props);
        this.state = {
            isFocused: false,
        }
        this.animatedText = new Animated.Value(this.props.value === '' ? 0 : 1);
        this.animatedTextField = new Animated.Value(0);
    }

    handleFocus = () =>  {
        this.setState({
            isFocused: true
        });
    }

    handleBlur = () => {
        this.setState({
            isFocused: false
        });
    }

    componentDidUpdate = () => {
        Animated.timing(this.animatedText, {
            toValue: (this.state.isFocused || this.props.value !== '') ? 1 : 0,
            duration: 200,
            easing: Easing.linear
        }).start();
        Animated.timing(this.animatedTextField, {
            toValue: this.state.isFocused ? 1 : 0,
            duration: 200,
            easing: Easing.linear
        }).start();
    }

    render() {
        const { label, ...props } = this.props;
        const labelStyle = {
            backgroundColor: whiteColor,
            color: this.animatedText.interpolate({
                inputRange: [0, 1],
                outputRange: ['#aaa', '#000']
            }),
            fontSize: this.animatedText.interpolate({
                inputRange: [0, 1],
                outputRange: [20, 14]
            }),
            left: 5,
            paddingHorizontal: 5,
            position: 'absolute',
            top: this.animatedText.interpolate({
                inputRange: [0, 1],
                outputRange: [26, 8]
            }),
            zIndex: 999
        };

        return (
            <View style={{ paddingTop: 18 }}>
                <Animated.Text style={labelStyle}>{label}</Animated.Text>
                <Animated.View style={{
                    borderColor: this.animatedTextField.interpolate({
                        inputRange: [0, 1],
                        outputRange: ['#555', primaryColor]
                    }),
                    borderRadius: 4,
                    borderWidth: 1,
                }}>
                    <TextInput
                        onBlur={this.handleBlur}
                        onFocus={this.handleFocus}
                        {...props}
                        style={{
                            color: '#000',
                            fontSize: 14,
                            height: 45,
                            paddingLeft: 10
                        }}
                    />
                </Animated.View>
            </View>
        );
    }
}

export default FloatingLabelInput;

然后在登录页面,然后是这样实现的:

<View>
  <FloatingLabelInput
    blurOnSubmit={false}
    editable={true}
    keyboardType={'email-address'}
    label="Email"
    onChangeText={this.handleEmailChange}
    onSubmitEditing={() => this.passwordInput && this.passwordInput.focus()}
    ref={(input) => { this.emailInput = input; }}
    returnKeyType="next"
    value={this.state.email}
  />
  <FloatingLabelInput
    editable={true}
    label="password"
    onChangeText={this.handlePasswordChange}
    onSubmitEditing={() => this.login()}
    ref={(input) => { this.passwordInput = input; }}
    value={this.state.password}
  />
</View>

我的理解是,通过引用下一个输入并拥有 .focus(),它应该可以工作,但是当我这样做时,它会抛出 this.passwordInput.focus() 未定义的错误

【问题讨论】:

    标签: javascript reactjs react-native


    【解决方案1】:

    您的 ref 不是 TextInput,它是 FloatingLabelInput,它没有焦点方法。您正在尝试关注不是 TextInput 的 FloatingLabelInput,而是包含 TextInput 的组件。

    您需要在这里使用forwardRef

    来自Facebook的示例

    const FancyButton = React.forwardRef((props, ref) => (
      <button ref={ref} className="FancyButton">
        {props.children}
      </button>
    ));
    
    // You can now get a ref directly to the DOM button:
    const ref = React.createRef();
    <FancyButton ref={ref}>Click me!</FancyButton>;
    

    【讨论】:

    • 这非常有效。在构建 SPA 时没有遇到过这个问题,因为我只是在输入标签,并且通常让 keypress enter 运行最终提交
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-16
    • 2018-09-11
    • 2017-08-07
    • 1970-01-01
    • 1970-01-01
    • 2020-10-23
    相关资源
    最近更新 更多