如何创建带有验证的简单多步骤登录
介绍
依赖项
让我们开始编码
结论
聚苯乙烯
介绍
假设你需要创建一个类似 Gmail 的多步骤登录表单。你正在使用 React 和全局存储(Redux、Mobx)进行开发,并且希望将组件彼此隔离以便将来复用。此外,你还需要为每个步骤添加验证。在本文中,我将展示我认为最简单、最正确的解决方案。完整解决方案可以在这里查看。
依赖项
首先,我们需要一个用于处理表单的库。在我看来,最好的解决方案是 react-hook-forms ( https://react-hook-form.com/ ),该网站详细描述了为什么这是一个优秀的解决方案。我自己也补充一下,这个库功能强大(验证、快速集成、控制器机制)并且文档完善。
对于验证,我们将使用 yup 库,它是一个非常强大且流行的库。
对于全局存储,我将使用 little-state-machine,因为它是一个非常简单的解决方案,并且基于 flux 架构构建。当然,你也可以使用 redux 或 mobx。
要将 yup 验证模式与 react-hook-form 集成,你还需要 @hookform/resolvers 包。
让我们开始编码
项目结构
该示例使用以下项目结构
- 步骤<-这里是所有表单步骤
- Congrats.js <- 最后一步,如果登录成功
- Email.js <- 第一步,输入邮箱继续登录
- Password.js <- 第二步,输入密码登录
- 店铺
- actions.js <- 包括所有操作,在我的情况下只有一个用于更新表单状态
- index.js <- 包括应用程序状态,在我的情况下只有表单状态
- App.js <- 主要组件,在我的例子中包括表单逻辑
- 指数
- App.css <- 应用程序样式
关于商店
我们将在存储中存储表单步骤和电子邮件数据的信息。让我们在 store/index.js 中添加这些信息。
const state = {
step: "Email",
email: ""
};
export default state;
现在让我们在 actions.js 中添加一个动作来更新表单
const updateFormState = (state, payload) => {
return {
...state,
...payload
};
};
export default updateFormState;
让我们在 index.js 中将存储添加到应用程序中
import { StrictMode } from "react";
import ReactDOM from "react-dom";
import App from "./App";
import { StateMachineProvider, createStore } from "little-state-machine";
import store from "./store";
// create out global form state
createStore(store);
const rootElement = document.getElementById("root");
ReactDOM.render(
<StrictMode>
<StateMachineProvider>
<App />
</StateMachineProvider>
</StrictMode>,
rootElement
);
基本逻辑
表单切换的逻辑及其处理程序将在 App.js 中(仅供示例)。我们需要将 store 连接到组件,以便接收表单信息并进行更新。
import "./styles.css";
import { useStateMachine } from "little-state-machine";
import updateFormState from "./store/actions";
// Here we import form steps
import EmailStep from "./steps/Email";
import CongratsStep from "./steps/Congrats";
import PasswordStep from "./steps/Password";
export default function App() {
// use hook for getting form state and actions
const { state, actions } = useStateMachine({ updateFormState });
// form handler for email step
const emailFormHandle = ({ email }) => {
actions.updateFormState({
email: email,
step: "Password"
});
};
// form handler for password step
const passwordFormHandle = ({ password }) => {
actions.updateFormState({
step: "Congrats"
});
};
// sign out handler
const signOutHandle = () => {
actions.updateFormState({
step: "Email"
});
};
return (
<div>
{state.step === "Email" && (
<EmailStep email={state.email} onSubmit={emailFormHandle} />
)}
{state.step === "Password" && (
<PasswordStep onSubmit={passwordFormHandle} />
)}
{state.step === "Congrats" && (
<CongratsStep email={state.email} onSignOut={signOutHandle} />
)}
</div>
);
}
JavaScript
表单步骤组件尽可能彼此隔离,并可在应用程序的其他部分复用。您只需添加默认值(如果存在)(例如电子邮件步骤)和表单处理函数即可。
步骤
电子邮件
输入邮箱地址是用户授权的第一步。需要检查输入邮箱地址的有效性,并记住它,以防用户在输入密码的步骤中返回并稍作修改。这看起来可能有点牵强,但当表单中有大量输入时,保存它们的状态对于节省用户时间非常有用。代码及注释如下:
import { useForm } from "react-hook-form";
// import our validation library
import * as yup from "yup";
// import integration library
import { yupResolver } from "@hookform/resolvers/yup";
import cn from "classnames";
// validation schema
const Schema = yup.object().shape({
// it says here that we want to check the input with the name email for the fact that the user will pass a string and this string matches email, you can change validation error message by changing text in email function argument
email: yup.string().email("Enter valid email please")
});
const EmailStep = (props) => {
// get form on Submit handler from parent component
const { onSubmit, email } = props;
// apply validations schema to react-hook-form form object
const { errors, register, handleSubmit } = useForm({
resolver: yupResolver(Schema),
// if user input his email before we can paste it to input as default value
defaultValues: {
email
}
});
// you can check all validations errors in console
console.log(errors);
return (
<form onSubmit={handleSubmit(onSubmit)}>
<div className="form-group">
<h2>Enter your email</h2>
</div>
<div className="form-group">
{/* check validation errors */}
{errors.email && (
<h4 className="invalid-msg">{errors.email.message}</h4>
)}
<input
// make input invalid if get email validation errors
className={cn(errors.email && "input-invalid")}
name="email"
ref={register}
placeholder="Your email"
/>
</div>
<div className="form-group">
<button type="submit">Next</button>
</div>
</form>
);
};
export default EmailStep;
你需要知道的是:
- 用户单击“提交”按钮(在我的情况下为“下一步”按钮)后将应用表单验证,但您可以在表单选项中更改此行为
- 所有验证错误都包含在错误对象中,该对象由 react-hook-form 生成,其键为输入名称(email),值是验证信息(请输入有效的email)
- 您可以通过 react-hook-form 表单对象使用默认的验证规则,无需任何库,但 yup 是更强大和灵活的包。
密码步骤
用户授权的最后一步。密码长度应大于6位,且包含拉丁字母。代码如下:
import { useForm } from "react-hook-form";
import * as yup from "yup";
import { yupResolver } from "@hookform/resolvers/yup";
import cn from "classnames";
const Schema = yup.object().shape({
password: yup
.string()
.min(6, "Password is too short")
.matches(/[a-zA-Z]/, "Password can only contain Latin letters.")
});
const PasswordStep = (props) => {
const { onSubmit } = props;
const { errors, register, handleSubmit } = useForm({
resolver: yupResolver(Schema)
});
console.log(errors);
return (
<form onSubmit={handleSubmit(onSubmit)}>
<div className="form-group">
<h2>Enter your password</h2>
</div>
<div className="form-group">
{errors.password && (
<h4 className="invalid-msg">{errors.password.message}</h4>
)}
<input
className={cn(errors.password && "input-invalid")}
name="password"
type="password"
ref={register}
placeholder="Your password"
/>
</div>
<div className="form-group">
<button type="submit">Sign In</button>
</div>
</form>
);
};
export default PasswordStep;
最后一步
最后让我们向用户显示祝贺消息
const CongratsStep = (props) => {
const { email, onSignOut } = props;
return (
<div className="form-group">
<h2>
Hello, {email}
<button onClick={onSignOut}>Sign Out</button>
</h2>
<img src="https://i.giphy.com/6nuiJjOOQBBn2.gif" alt="" />
</div>
);
};
export default CongratsStep;
结论
就这样。我们创建了独立的表单步骤,为邮箱地址添加默认值,为每个表单步骤添加验证规则,并使用了我们最强大、最流行的软件包(除了 little-state-machine)。
如果您感兴趣,我可以用 TypeScript、MUI 和 Mobx 或 Redux 软件包来演示这些示例。
聚苯乙烯
这是我的第一篇文章,英语不是我的母语,希望一切都清楚,你度过了愉快的时光:)如果你在理解文本方面有问题(因为我不太了解该语言),你可以随时查看我的代码,它比任何文字都更有说服力
鏂囩珷鏉ユ簮锛�https://dev.to/alex1998dmit/how-to-create-simple-many-step-form-with-validation-3g4f