React-native hooks 表单验证

Posted

技术标签:

【中文标题】React-native hooks 表单验证【英文标题】:React-native hooks form validation 【发布时间】:2021-01-29 16:19:08 【问题描述】:

我正在练习 React Native。我创建了两个输入字段。用户可以在其中键入电子邮件和密码。我用三个变量创建了一个状态,它们是电子邮件、密码和错误消息。对于电子邮件验证,我使用了 Firebase。当提交表单而不填写任何我得到invalid error 时,这意味着我的firebase auth 有效。但是当用电子邮件和密码字段填写表格时,我收到错误Error: signInWithEmailAndPassword failed: First argument "email" must be a valid string.

当我控制台记录handleChange Events。我得到一堆对象。它看起来像这样:

am event SyntheticEvent 
  "_dispatchInstances": FiberNode 
    "tag": 5,
    "key": null,
    "type": "RCTSinglelineTextInputView",
  ,
  "_dispatchListeners": [Function _onChange],
  "_targetInst": FiberNode 
    "tag": 5,
    "key": null,
    "type": "RCTSinglelineTextInputView",
  ,
  "bubbles": undefined, and so on ........

我使用的是onChange,而不是 React native 的 onChangeText。我也试过onChangeText,但我得到了同样的错误。有没有办法在功能组件中提交 react native 表单?

这是我的登录表单

import React,  ReactElement, useState  from 'react';
import styled from 'styled-components';
import  Text, View, TextInput, TouchableOpacity  from 'react-native';
import * as firebase from 'firebase';

interface Props 



export default function Login( : Props): ReactElement 

  const [state, setState] = useState(
    email: '',
    password: '',
    errorMessage: null
  )


  const  errorMessage  = state;

  const handleChange = event => 
    console.log("I am event", event);
    setState(
      ...state,
      [event.target.id]: event.target.value
    );
  ;

  const handleSubmit = event => 
    event.preventDefault();
    const  email, password  = state;
    firebase.auth().signInWithEmailAndPassword(email, password).catch(error => setState( errorMessage: error.message ))
  ;


  // const handleSubmit = () => 
  //   const  email, password  = state;
  //   firebase.auth().signInWithEmailAndPassword(email, password).catch(error => setState( errorMessage: error.message ))
  // 

  return (
    <Container>
      <Greeting >`Hello again. \nWelcome Back`</Greeting>
      <ErrorMessageContainer >
        ErrorMessage && <ErrorMessage >errorMessage </ErrorMessage>
      </ErrorMessageContainer>
      <Form style= marginHorizontal: 30 >
        <View>
          <InputTitle>
            Email Address
          </InputTitle>
          <Input
            autoCapitalize="none"
            onChange=handleChange
            value=state.email
            id="email"
          ></Input>
        </View>
        <View style= marginTop: 32 >
          <InputTitle>
            password
         </InputTitle>
          <Input
            secureTextEntry
            autoCapitalize="none"
            onChange=handleChange
            value=state.password
            id="password"
          ></Input>
        </View>
      </Form>
      <SubmitButton style= marginHorizontal: 30 
        onPress=handleSubmit
      >
        <ButtonText>
          Sign In
                </ButtonText>
      </SubmitButton>
      <TouchableOpacity style= marginTop: 30, alignItems: "center"  >
        <ButtonText style= color: "black", fontSize: 15 >
          New to Social App?
                  <Text style= fontWeight: "500", color: "#E9446A" > Sign up </Text>
        </ButtonText>
      </TouchableOpacity>
    </Container>
  )
;



const Container = styled.View`
          flex:1;

        `

const Greeting = styled.Text`
          margin-top: 30px;
          font-weight: 400;
          text-align: center;
          font-size: 20px
        `

const ErrorMessageContainer = styled.View`
          height: 72px;
          align-items: center;
          justify-content: center;
          margin-top: 30px;

        `


const ErrorMessage = styled.Text`
          font-weight: 500;
          color: red;
          font-size: 15px;
        `

const Form = styled.View`
          margin-bottom: 48px;
        `;
const InputTitle = styled.Text`
          color: #8a8f9e;
          font-size: 10px;
          text-transform: uppercase;
        `

const Input = styled.TextInput`
          border-bottom-color: #8a8f9e;
          border-bottom-width: 0.5px;
          height: 40px;
          font-size: 15px;
          color: black;
        `;
const SubmitButton = styled.TouchableOpacity`
          background-color: #00203FFF;
          height: 52px;
          border-radius: 4px;
          align-items: center;
          justify-content: center;

        `;
const ButtonText = styled.Text`
          color: #fff;
          font-weight: 500;
        `

【问题讨论】:

为什么不先在handleChange中使用console.log e,这样我们就可以仔细检查email的值了? 它未定义。我查过了 您从哪个库导入输入组件? 从哪里来:D. 我敢肯定,我在代码中犯了愚蠢的错误。因为我是新人react-native。我看不到错误 【参考方案1】:

我建议你使用 react-native 库中的 TextInput: https://reactnative.dev/docs/handling-text-input

做这样的事情:

   const handleChange = (label, value) => 
    setstate(
      ...state,
      [label]: value
    )
  

 <TextInput
                autoCapitalize="none"
                onChangeText=text => handleChange("email",text)
                value=email
                id="email"
              >
</TextInput>

我希望这会有所帮助,并且不要忘记仔细检查导入每个组件以避免错误。

【讨论】:

以上是关于React-native hooks 表单验证的主要内容,如果未能解决你的问题,请参考以下文章

反应表单钩子如何验证选择选项

如何在反应中验证多步表单

带有 Chakra UI 的 React-hook-form 未在 NextJS 中显示验证错误消息

Django 表单(中下)- 自定义钩子进行数据验证

如何使 react-hook-form 在一页中使用多个表单?

react-hook-form yup 解析器,reactStrap 解决子组件错误的问题