简体   繁体   English

似乎无法聚焦下一个 TextInput (React-Native)

[英]Can't seem to focus the next TextInput (React-Native)

I've got a little experience with React, but still trying to figure out React-Native.我对 React 有一点经验,但仍在尝试弄清楚 React-Native。 I'm working on a little project, and I'm working on a login form.我正在做一个小项目,我正在做一个登录表单。 I would like to have it so that when you press next on the keyboard, then it moves on to the next input field.我想要它,以便当您按键盘上的下一步时,它会移动到下一个输入字段。 I've made a custom TextInput component, since I will be using it a few different places.我制作了一个自定义 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;

and then on the login page, then it's implemented like this:然后在登录页面上,它是这样实现的:

<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>

My understanding is that by referancing the next input and having .focus(), then it should work, but when I do this, then it throws an error that this.passwordInput.focus() is undefined我的理解是,通过引用下一个输入并使用 .focus(),它应该可以工作,但是当我这样做时,它会抛出一个错误,即 this.passwordInput.focus() 未定义

Your ref is not a TextInput, it's a FloatingLabelInput and it doesn't have a focus method.您的 ref 不是 TextInput,而是 FloatingLabelInput,并且没有 focus 方法。 You are trying to focus FloatingLabelInput which is not a TextInput, rather it's a component that contains a TextInput.您正在尝试关注 FloatingLabelInput,它不是 TextInput,而是包含 TextInput 的组件。

You need to use forwardRef here.您需要在此处使用forwardRef

Example from Facebook来自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>;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM