如何用React Alert进行客户端验证

305 阅读7分钟

用React Alert进行客户端验证

Javascript支持一项功能,可以验证用户从Web应用程序发送到Web服务器的数据是否有效。

这个功能让前端开发者有能力在数据被发送到Web服务器之前验证用户的输入数据。

在这篇文章中,我们将看看如何使用npm包react-alert来验证输入数据。react-alert ,在用户输入数据无效的情况下,可以更容易地将错误信息反馈给用户。

前提条件

要继续学习本教程,你需要。

  1. [Node.js]10.x或更新版本。
  2. [NPM]5.10或更新版本。
  3. 对Javascript中条件语句的了解。
  4. React.js的基本知识。
  5. DOM操作的基本知识。

概述

在React之前,vanilla JS是客户端验证的首选解决方案。人们需要了解DOM操作和事件处理的基本原理。

这个验证过程的目的是检查用户发送给服务器的数据是否合适。事件监听器将帮助我们监听网页上发生的事件。

这些事件的范围包括点击一个按钮onClick ,鼠标在网页上某个特定元素上的悬停效果onMouseOver ,使用onSubmit ,提交输入表单中的详细信息,以及更多。

在vanilla JS中执行DOM操作并不是什么大问题,因为DOM是可用的。但在React中,DOM是不可用的,而是有一个虚拟的DOM。

虽然在React中操作DOM的方式与vanilla JS相同,但也有一些怪异之处。一个是Document对象在React中是不可用的。这是因为它与Node.js捆绑在一起,而Node.js并不运行在网络浏览器的客户端。

开始使用

为了能够在React中执行客户端验证,让我们从安装必要的npm 依赖项开始。

我将使用Next.js来引导我的React应用程序。因为它的简单性,它的文件夹结构,以及其他许多好处。

你不需要使用Next.js。你也可以。

  1. 使用[create-react-app]创建一个React应用。
  2. 或者用[Parcel.js]引导你的React应用。

请随意使用你觉得合适的方法。

要开始使用Next.js,在你的工作区,打开终端并运行以下命令。

npx create-next-app name-of-your-app

这将安装Next.js和创建React应用程序所需的所有依赖项。因为本文的重点是在React中使用react-alert 进行客户端验证。我们还需要将react-alert 包添加到项目所需的依赖项列表中。下面的命令将为我们处理这个问题。

npm install react-alert –save-dev

对JavaScript中的条件语句如何操作有基本的了解,会加快你在项目的客户端编写验证函数的过程。

一个基本的条件语句如下所示,即if 语句。它是JavaScript中最常用的语句之一,它只在传递的参数为真时才执行代码。

if (username) {
  console.log(username);
}

上面的代码片段检查了username 这个变量的有效性。如果它没有被定义,一个引用错误将显示在控制台 "username is not defined"。

const username = "Malete";
if (username) {
  console.log(username);
}

// Malete is printed on the console.

上面的代码在控制台显示Malete ,因为username 已经定义。

有些情况下,条件语句并没有在大括号的结尾处停止。如果有其他条件需要检查,我们可以将下一个条件语句连锁起来,直到得到所需的结果。

if 语句并驾齐驱的其他条件语句是elseelse if 。正如它们的命名惯例所暗示的,else 是在没有条件需要检查的时候使用的。而else if 是在有更多条件需要检查时使用的。

这也是我们在本项目中实现客户端验证时要用到的原则。

设置验证脚本

在创建验证脚本之前,让我们看一下应用程序的文件夹结构。这样,在我们进行的过程中,遍历应用程序结构的过程就不会变得混乱或含糊。

|--pages
| |--_app.js
| |--index.js
|--src
| |--container
|   |--App
|    |--index.js
|--utils
  |--checks.js
  |--alert-template.js

上面的结构是真实应用结构的一个节选。但是,为了简洁起见,以及我们将与之互动的文件的重要程度,上面的结构符合本文的范围。

上面的结构显示,checks.js 文件位于utils 文件夹内。checks.js 是我们所有客户端验证逻辑的地方。

由于我们要为网络表单交互/编写这些逻辑,我们需要寻找一种方法来针对在客户端接收用户数据的输入元素。幸运的是,浏览器提供了一些DOM API,我们可以用它们来实现这一目标。请看下面的一个例子。

<input type="”text”" name="”fullname”" id="”fullname”" className="”fullname”" />
const fullnameInputField = document.querySelector(“#fullname”)

console.log(fullnameInputField)

上面的代码将HTML代码记录到控制台。你可以通过打开浏览器的开发工具来检查结果。在谷歌chrome上,快捷键ctrl + shift + i ,可以打开控制台。

如果我们通过输入元素的className ,上面的代码段将变为。

const fullnameInputField = document.querySelector(“.fullname”)

请注意,哈希符号(#) 已经变成了句点符号(.) ,因为我们是通过其className属性来定位该DOM节点。

现在让我们来看看下面的验证片段。

// utils/check.js file

let errMsg;

const validateSignUp = (email, password, confirmPassword, alert) => {
  // targeting all form fields
  const emailInput = document.querySelector("#email");
  const passwordInput = document.querySelector("#pwd");
  const confirmPasswordInput = document.querySelector("#pwd_conf");

  if (!email) {
    alert.error("Please input your email address");
    emailInput.focus();
    errMsg = false;
  } else if (password === "") {
    alert.error("Please provide your password!");
    passwordInput.focus();
    errMsg = false;
  } else if (password.value <= 7) {
    alert.error("Your password must have 8 characters or greater");
    passwordInput.focus();
    errMsg = false;
  } else if (
    typeof password !== "undefined" &&
    typeof confirmPassword !== "undefined"
  ) {
    if (password !== confirmPassword) {
      alert.error("Passwords don't match");
      confirmPasswordInput.focus();
      errMsg = false;
    }
  } else {
    alert.success("You've signed up successfully. Proceed to login");
    errMsg = true;
  }
  return errMsg;
};

export default signUpCheck;

我们将在接下来的时间里对每个代码段的作用进行分解。

  • 将表单值作为道具传递

    上面的片段是一个辅助函数,在输入的表单数据被发送到后端服务器之前对其进行验证。该函数接受电子邮件、密码、confirmPassword和警报作为参数。

let errMsg;

const validateSignUp = (email, password, confirmPassword, alert) => {};

我们将alert 作为参数传递给函数,这样当它被导入到应用程序组件时,我们就可以访问它。其他参数也是如此。

errMsg 变量存储了来自我们验证逻辑的错误信息。这就是为什么我们用let 关键字声明它,所以它可以在代码执行过程中被重新分配到任何其他值。

  • 条件性语句

    • 第一个条件是检查电子邮件字段是否为空,如果是,则使用alert.error() 方法在用户界面上显示出一个警告错误信息。

    alert.error() 方法需要一个字符串作为参数。这个字符串将被显示在用户界面上,浏览器确保输入字段处于焦点位置,以便吸引用户的注意力。

    if (!email) {
      alert.error("Please input your email address");
      emailInput.focus();
      errMsg = false;
    }
    
    • 下一个条件是检查用户是否输入了任何密码。如果密码表单字段中没有任何数值,浏览器中就会弹出一个错误。而下一个条件则是检查密码的长度是否有效。
    else if (password === "") {
        alert.error("Please provide your password!");
        passwordInput.focus();
        errMsg = false;
    } else if (password.value <= 7) {
        alert.error("Your password must have 8 characters or greater");
        passwordInput.focus();
        errMsg = false;
    }
    
    • 下面的条件语句,检查第一个和第二个密码之间是否存在匹配。该逻辑采用了JavaScript中的闭包来执行这个特殊的验证。
    else if (typeof password !== "undefined" && typeof confirmPassword !== "undefined") {
        if (password != confirmPassword) {
            alert.error("Passwords don't match");
            confirmPasswordInput.focus();
            errMsg = false;
        }
    }
    

    它对两个密码字段进行条件执行,以确保它们都不是未定义的,也就是说,它们不是空字段。如果这第一个条件通过,下一个条件就会运行。如果没有,下一个就不会运行。

    • 如果所有的条件都被检查了,警报窗口就会出现成功的文字。

使用验证器

现在我们已经设置好了验证脚本,并且已经掌握了脚本中的内容,现在是时候让它进入应用程序本身了。我们将看一下完成这一工作的步骤。

首先,我们需要把验证脚本和 react-alert 依赖关系一起导入到应用组件中。为了简洁起见,我不会对React组件结构做太多解释,因为它是本文的前提条件之一。

// src/App/index.js file

import React from “react”
import { withAlert } from "react-alert";
import validateSignUp from "../../utils/checks";

const SignUp = ({ alert }) => {
    const [fullname, setFullName] = React.useState("");
    const [email, setEmail] = React.useState("");
    const [password, setPassword] = React.useState("");
    const [pwdConfirm, setPwdConfrim] = React.useState("");


    // handles the submit event once the user clicks on the button
    const handleSubmit = (e) => {
        e.preventDefault();

        const validate = validateSignUp(email, password, pwdConfirm, alert || " ");

        if (validate) {
            alert.success("You've signed up successfully. Proceed to login");
        }
    };

return (
    <section>
        <div>
            <form onSubmit={handleSubmit}>
               <div>
                <p>Email Address</p>
                  <input
                    type="email"
                    name="email"
                    id="email"
                    placeholder="youremail@example.com"
                    value={email}
                    onChange={(e) => setEmail(e.target.value)}
                  />
               </div>
               <div>
                <p>Enter Password</p>
                  <input
                    name="password"
                    id="pwd"
                    placeholder="password"
                    value={password}
                    onChange={(e) => setPassword(e.target.value)}
                  />
               </div>
               <div>
                <p>Confirm Password</p>
                <input
                  name="confirm__pwd"
                  id="pwd__conf"
                  placeholder="enter your password again"
                  value={pwdConfirm}
                  onChange={(e) => setPwdConfrim(e.target.value)}
                />
                <button>Sign up</button>
                </div>
            </form>
        </div>
    </section>
  );
};

export default withAlert()(SignUp);

看一下handleSubmit 函数,你会注意到signUpCheck 验证器的参数是如何被使用的。在这个函数中,所有的条件都必须满足,才能提交表单。

const validate = validateSignUp(email, password, pwdConfirm, alert ||" ");

    if (validate) {
      alert.success("You've signed up successfully. Proceed to login");
    }
};
  • 设置警报模板

这一步涉及到向我们的应用程序提供react-alert 模板API。没有这个,错误信息就不会显示在网页上。让我们先看一下下面的设置。

我们首先要创建一个组件,作为错误信息的容器。在utils 文件夹中,我们将添加警报模板的所有逻辑。

// alert-template.js file

import React from "react";

import { transitions, positions, Provider as AlertProvider } from "react-alert";

const AlertTemplate = ({ message, options }) => {
  return (
    <div className={options.type === "success" ? "msg-success" : "msg-error"}>
      <p>{message}</p>
    </div>
  );
};

// this component serves as the container
// that holds/displays the error messages due to the validation
// script that runs on all the app components that have an
// input field
const Message = ({ children }) => {
  const options = {
    position: positions.TOP_RIGHT,
    timeout: 3500,
    offset: "0px",
    transition: transitions.SCALE,
  };

  return (
    <AlertProvider template={AlertTemplate} {...options}>
      {children}
    </AlertProvider>
  );
};

export default Message;

上面的片段显示了一个三元组格式的条件语句。如果options.type 是 "成功",它将className设置为msg-success ,否则将className设置为msg-error

msg-success 给警报模板/模版一个绿色背景,而msg-error 给模板添加一个红色背景。

现在让我们继续添加模板作为应用程序组件的父元素。这可以通过编辑_app.js 文件的内容来完成。

// _app.js file

import React from “react”
import Message from "../src/utils/alert-template";
import Head from “next/head”

function App({ Component, pageProps }) {
    return (
      <React.Fragment>
       <Head>
         <link rel="icon" href="#" />
         <meta
           name="viewport"
           content="minimum-scale=1, initial-scale=1, width=device-width"
         />
         <title>React alert example</title>
       </Head>
       <Message>
          <Component {...pageProps} />
       </Message>
      </React.Fragment>
    );
}

export default App;

我们已经向应用程序组件提供了警报模板。现在让我们把SignUp表单组件导入到应用组件中。pages/index.js

import React from "react";
import SignUp from "../src/container/App";

export default function IndexPage() {
  return <SignUp />;
}

收尾工作

你已经注意到我们没有深入研究这个项目的风格。你可以按照你的喜好来设计你的项目。