React-Native:Formik ref 无法获取价值

React-Native: Formik ref fails to get value

我在 react-native 中有一个带有 formik 形式的虚拟登录代码

import React, { Component } from "react";
import {
  TextInput,
  Text,
  Alert,
  Image,
  View,
  TouchableOpacity,
  SafeAreaView,
  ScrollView
} from "react-native";
import styles from "./Styles/LoginStylesheet";
import { KeyboardAccessoryNavigation } from "react-native-keyboard-accessory";
import { Formik } from "formik";
import schemaObject, { initialValues, refs } from "./Validations/LoginValidations";

export default class LoginView extends Component {

  constructor(props) {
    super(props);
    this.state = {
      activeInputIndex: 0
    };
  }

  handleFocus = index => () => {
    this.setState({
      activeInputIndex: index
    });
  };

  handleFocusNext = () => {
    if (this.state.activeInputIndex + 1 >= refs.length) {
      return;
    }
    refs[this.state.activeInputIndex + 1].focus();
  };

  handleFocusPrevious = () => {
    if (this.state.activeInputIndex - 1 < 0) {
      return;
    }
    refs[this.state.activeInputIndex - 1].focus();
  };

  handleLogin = () => {
    console.log("ACTIOn");
      // this.formik.handleSubmit();
  };

  render() {
    return (
      <View style={styles.safeAreaView}>
        <SafeAreaView style={styles.safeAreaView}>
          <ScrollView style={styles.superView}>
            <Formik {/* LINE 56  */}
              initialValues={initialValues}
              onSubmit={values => Alert.alert(JSON.stringify(values))}
              validationSchema={schemaObject}
              ref={p => (this.formik = p)}
            >
              {({
                values,
                handleChange,
                errors,
                setFieldTouched,
                touched,
                isValid,
                handleSubmit
              }) => (
                <View style={styles.superView}>
                  <View style={styles.logoParentView}>
                    <Image
                      source={require("../../Resources/Assets/Login/aptihealth_logo.png")}
                      resizeMode={"contain"}
                      style={styles.logo}
                    />
                  </View>

                  <View style={styles.emailParentView}>
                    <Text style={styles.titleLabel}>Email Id</Text>
                    <TextInput
                      value={values.emailId}
                      onChangeText={handleChange("emailId")}
                      onBlur={() => setFieldTouched("emailId")}
                      placeholder="Email Id"
                      style={styles.textInput}
                      autoCorrect={false}
                      onFocus={this.handleFocus(0)}
                      ref={input => {
                        refs[0] = input;
                      }}
                    />
                    {touched.emailId && errors.emailId && (
                      <Text style={{ fontSize: 10, color: "red" }}>
                        {errors.emailId}
                      </Text>
                    )}
                  </View>

                  <View style={styles.passwordParentView}>
                    <Text style={styles.titleLabel}>Password</Text>
                    <TextInput
                      value={values.password}
                      onChangeText={handleChange("password")}
                      placeholder="Password"
                      onBlur={() => setFieldTouched("password")}
                      style={styles.textInput}
                      autoCorrect={false}
                      secureTextEntry={true}
                      onFocus={this.handleFocus(1)}
                      ref={input => {
                        refs[1] = input;
                      }}
                    />
                    {touched.password && errors.password && (
                      <Text style={{ fontSize: 10, color: "red" }}>
                        {errors.password}
                      </Text>
                    )}
                  </View>

                  <View style={styles.forgotPasswordParentView}>
                    <TouchableOpacity
                      style={styles.forgotpasswordButton}
                      activeOpacity={0.7}
                    >
                      <Text>Forgot Password?</Text>
                    </TouchableOpacity>
                  </View>

                  <View style={styles.loginParentView}>
                    <TouchableOpacity
                      onPress={() => {
                        console.log("VALUES: ", values, this.formik);
                        this.handleLogin();
                      }}
                      style={styles.loginButton}
                      activeOpacity={0.7}
                    >
                      <Text style={styles.loginText}>Login</Text>
                    </TouchableOpacity>
                  </View>

                  <View style={styles.seperaterParentView}>
                    <View style={styles.seperaterView} />
                    <Text style={styles.seperaterText}>OR</Text>
                    <View style={styles.seperaterView} />
                  </View>

                  <View style={styles.faceIdLoginParentView}>
                    <Image
                      source={require("../../Resources/Assets/face_id_small_color/face_id_small_color.png")}
                      resizeMode={"contain"}
                    />
                    <TouchableOpacity style={styles.faceIdButton}>
                      <Text>Sign In with Face ID</Text>
                    </TouchableOpacity>
                  </View>
                  <View style={styles.signUpParentView}>
                    <TouchableOpacity style={styles.signupButton}>
                      <Text>Sign Up for Account Here</Text>
                    </TouchableOpacity>
                  </View>
                </View>
              )}
            </Formik>
          </ScrollView>
        </SafeAreaView>
        <KeyboardAccessoryNavigation
          nextDisabled={false}
          previousDisabled={false}
          nextHidden={false}
          previousHidden={false}
          onNext={this.handleFocusNext}
          onPrevious={this.handleFocusPrevious}
          avoidKeyboard
        />
      </View>
    );
  }
}

我正在尝试在登录操作中控制 formik ref 获取未定义的值并出现调试错误

ExceptionsManager.js:126 Warning: Function components cannot be given refs. Attempts to access this ref will fail. Did you mean to use React.forwardRef()?

Check the render method of `LoginView`.
    in Formik (at LoginView.js:56)

我不知道为什么它会变得不确定 ??

你应该看看this issue

你的问题就在这里

<Formik
  initialValues={initialValues}
  onSubmit={values => Alert.alert(JSON.stringify(values))}
  validationSchema={schemaObject}
  ref={p => (this.formik = p)} {/* passing this ref will throw the error */}
>

在最新版本的 Formik 中,他们将 Formik 更改为功能组件,如问题中所述,如果您通过 ref's,则会出现此错误。

您可以查看有关该问题的建议,或者等到他们发布包含更正的更新。

编辑:

Formik 进行了更新,现在您可以将 ref 与道具一起使用 innerRef

请参阅this comment

你应该把它改成

<Formik
  initialValues={initialValues}
  onSubmit={values => Alert.alert(JSON.stringify(values))}
  validationSchema={schemaObject}
  {/* using innerRef instead of ref*/}
  innerRef={p => (this.formik = p)} {/* this will give you the formik bag */}
>

这样你就可以调用 this.formik.handleSubmit(),就像你想做的那样。