React 中创建简单和复杂表单的最佳库
由 Mux 主办的 DEV 全球展示挑战赛:展示你的项目!
在 React 中创建表单是一项复杂的任务。它涉及处理所有输入状态及其变化,并在表单提交时验证输入内容。
对于简单的表单,通常比较容易管理。但随着表单变得越来越复杂,需要添加各种验证,任务就变得很繁琐了。
因此,与其手动编写所有代码并处理带有验证逻辑的复杂表单,我们可以使用最流行的 React 库react-hook-form来实现这一点。
与Formik、React Final Form等相比,它是最流行的 React 表单创建库,我将其用于我所有的客户项目。
本文将详细介绍如何使用react-hook-form库。
那么,我们开始吧。
为什么 react-hook-form 库是 React 中最受欢迎的表单库
以下是 react-hook-form 成为创建 React 表单的热门选择的一些原因。
- 与替代方案相比,该应用程序的重新渲染次数更少,因为它使用 refs 而不是 state。
- 与 formik、react-final-form 和其他替代方案相比,您需要编写的代码量更少。
- react-hook-form 与 yup 库很好地集成,用于模式验证,因此您可以组合自己的验证模式。
- 与其他替代方案相比,安装时间更短。
请访问react-hook-form网站查看更详细的比较信息。
如何在不使用库的情况下创建表单
在使用 react-hook-form 库创建表单之前,让我们先创建一个不使用任何库的简单表单。
请查看以下代码:
import React, { useState } from "react";
import "./styles.css";
export default function App() {
const [state, setState] = useState({
email: "",
password: ""
});
const handleInputChange = (event) => {
const { name, value } = event.target;
setState((prevProps) => ({
...prevProps,
[name]: value
}));
};
const handleSubmit = (event) => {
event.preventDefault();
console.log(state);
};
return (
<div className="App">
<form onSubmit={handleSubmit}>
<div className="form-control">
<label>Email</label>
<input
type="text"
name="email"
value={state.email}
onChange={handleInputChange}
/>
</div>
<div className="form-control">
<label>Password</label>
<input
type="password"
name="password"
value={state.password}
onChange={handleInputChange}
/>
</div>
<div className="form-control">
<label></label>
<button type="submit">Login</button>
</div>
</form>
</div>
);
}
这是一个代码沙盒演示。
上面的代码中只有两个输入字段,即和email,password以及一个提交按钮。
每个输入字段都添加了一个value处理onChange程序,以便我们可以根据用户的输入更新状态。
此外,我们还添加了一个handleSubmit方法,可以将表单中输入的数据显示在控制台中。
这样看起来没问题。但是如果我们需要添加诸如必填字段验证、最小长度验证、密码验证、电子邮件字段验证等验证,并且还需要显示相应的错误消息,该怎么办呢?
随着输入字段及其验证的数量增加,代码将变得越来越复杂和冗长。
如何安装 react-hook-form 库
在任何应用程序中,显示表单都是一项非常常见的需求。
那么,让我们来学习一下为什么要使用它以及如何使用它react-hook-form。为此,我们将创建一个新的 React 应用程序。
在终端运行以下命令,创建一个新的 React 项目:
create-react-app demo-react-hook-form
项目创建完成后,删除文件夹中的所有文件,并在文件夹内src创建新index.js文件。styles.csssrc
要安装该react-hook-form库,请在终端中执行以下命令:
npm install react-hook-form@7.38.0
OR
yarn add react-hook-form@7.38.0
在这里,我们将安装7.38.0该库的最新版本react-hook-form,该版本在撰写本文时是最新版本。
如何创建初始页面
打开src/index.js文件,并在其中添加以下内容:
import React from "react";
import ReactDOM from "react-dom/client";
import App from "./App";
const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(<App />);
请注意,以上代码使用的是 React 18+ 版本语法来渲染应用程序。
如果您使用的是 React 版本低于 18(您可以从package.json文件中确认),则将以下代码添加到您的src/index.js文件中。
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
ReactDOM.render(<App />, document.getElementById('root'));
现在,打开src/styles.css文件,并将这里的内容添加到文件中。
现在,在文件夹App.js内创建一个名为 `<filename>` 的新文件src,并写入以下内容:
import React from "react";
import "./styles.css";
export default function App() {
return (
<div className="App">
<form>
<div className="form-control">
<label>Email</label>
<input type="text" name="email" />
</div>
<div className="form-control">
<label>Password</label>
<input type="password" name="password" />
</div>
<div className="form-control">
<label></label>
<button type="submit">Login</button>
</div>
</form>
</div>
);
}
这里,我们刚刚在表单中添加了电子邮件和密码字段。
如何使用 react-hook-form 创建基本表单
该react-hook-form库提供了一个useForm钩子,我们可以利用它来处理表单。
useForm像这样导入钩子:
import { useForm } from 'react-hook-form';
你可以useForm像这样使用钩子:
const {
register,
handleSubmit,
formState: { errors },
} = useForm();
这里,
register这是一个由钩子函数提供的函数useForm。我们可以将其分配给每个输入字段,以便react-hook-form跟踪输入字段值的变化。handleSubmit这是表单提交后我们可以调用的函数。errors是对象中的一个嵌套属性formState,用于存储验证错误(如果有)。
现在,将文件内容替换App.js为以下代码:
import React from "react";
import { useForm } from "react-hook-form";
import "./styles.css";
export default function App() {
const {
register,
handleSubmit,
formState: { errors }
} = useForm();
const onSubmit = (data) => {
console.log(data);
};
return (
<div className="App">
<form onSubmit={handleSubmit(onSubmit)}>
<div className="form-control">
<label>Email</label>
<input type="text" name="email" {...register("email")} />
</div>
<div className="form-control">
<label>Password</label>
<input type="password" name="password" {...register("password")} />
</div>
<div className="form-control">
<label></label>
<button type="submit">Login</button>
</div>
</form>
</div>
);
}
useForm在上面的代码中,我们通过向每个函数传递一个唯一的名称,为每个从钩子函数获取的输入字段添加了一个注册函数,register如下所示:
{...register("email")}
我们使用展开运算符,因此会将所有必需的事件处理程序(如、)以及该输入字段的其他属性react-hook-form展开。onChangeonBlur
如果在组件内部添加一个元素console.log({ ...register("email") });,您将看到它返回的内容,如下所示:
我们还添加了onSubmit传递给handleSubmit方法的函数,如下所示:
<form onSubmit={handleSubmit(onSubmit)}>
...
请注意,您需要register为每个输入字段添加一个唯一的函数名称,以便react-hook-form跟踪数据的变化。
当我们提交表单时,该handleSubmit函数将处理表单提交。它会将用户输入的数据发送到另一个onSubmit函数,该函数会将用户数据记录到控制台。
const onSubmit = (data) => {
console.log(data);
};
现在,运行npm start`or`yarn start命令启动应用程序,您将看到以下屏幕:
这是一个代码沙盒演示。
如您所见,当我们提交表单时,用户输入的详细信息会显示在控制台中。
此外,与没有使用该功能的代码react-hook-form(我们在本文开头的代码沙盒演示中看到了该代码)相比,这段代码要简单得多。
这是因为我们不需要为每个输入字段添加valueandonChange处理程序,也不需要自己管理应用程序状态。
如何为表单添加验证
现在,让我们为输入字段添加必填字段和最小长度验证。
为了添加验证功能,我们可以register像这样将一个对象作为第二个参数传递给函数:
<input
type="text"
name="email"
{...register("email", {
required: true
})}
/>
<input
type="password"
name="password"
{...register("password", {
required: true,
minLength: 6
})}
/>
这里,对于电子邮件字段,我们指定了必填字段验证。对于密码字段,我们指定了必填字段和最小6个字符长度验证。
当验证失败时,errors来自useForm钩子的对象将填充验证失败的字段。
因此,我们将使用该errors对象来显示自定义错误消息。
打开App.js文件,并将其内容替换为以下内容:
import React from "react";
import { useForm } from "react-hook-form";
import "./styles.css";
export default function App() {
const {
register,
handleSubmit,
formState: { errors }
} = useForm();
const onSubmit = (data) => {
console.log(data);
};
return (
<div className="App">
<form onSubmit={handleSubmit(onSubmit)}>
<div className="form-control">
<label>Email</label>
<input
type="text"
name="email"
{...register("email", {
required: true,
pattern: /^[^@ ]+@[^@ ]+\.[^@ .]{2,}$/
})}
/>
{errors.email && errors.email.type === "required" && (
<p className="errorMsg">Email is required.</p>
)}
{errors.email && errors.email.type === "pattern" && (
<p className="errorMsg">Email is not valid.</p>
)}
</div>
<div className="form-control">
<label>Password</label>
<input
type="password"
name="password"
{...register("password", {
required: true,
minLength: 6
})}
/>
{errors.password && errors.password.type === "required" && (
<p className="errorMsg">Password is required.</p>
)}
{errors.password && errors.password.type === "minLength" && (
<p className="errorMsg">
Password should be at-least 6 characters.
</p>
)}
</div>
<div className="form-control">
<label></label>
<button type="submit">Login</button>
</div>
</form>
</div>
);
}
现在查看该应用程序,您将看到以下屏幕:
这是一个代码沙盒演示。
如您所见,提交表单后,当我们尝试在输入字段中输入值时,每个输入字段都会立即出现验证错误。
如果任何输入字段出现错误,该errors对象将填充我们用于显示自定义错误消息的错误类型,如下所示:
{errors.email && errors.email.type === "required" && (
<p className="errorMsg">Email is required.</p>
)}
{errors.email && errors.email.type === "pattern" && (
<p className="errorMsg">Email is not valid.</p>
)}
这里,根据错误类型,我们会显示不同的错误信息。
使用ES11 可选链式运算符,您可以进一步简化上述代码,如下所示:
{errors.email?.type === "required" && (
<p className="errorMsg">Email is required.</p>
)}
{errors.email?.type === "pattern" && (
<p className="errorMsg">Email is not valid.</p>
)}
同样地,我们也添加了密码字段验证功能。
另外,正如您所看到的,如果某个输入字段存在验证错误,则在提交表单时,该输入字段会自动获得焦点。
此外,只要存在验证错误,表单就不会提交。如果您查看浏览器控制台,就会发现console.log只有在表单有效且没有错误的情况下才会打印该声明。
因此,使用这种方法react-hook-form减少了我们需要编写的代码量。此外,验证功能也具有响应式设计,一旦字段有效,错误消息就会立即消失。
但是,随着每个字段的验证次数增加,条件检查和错误信息代码也会随之增加。因此,我们可以进一步重构代码,使其更加简洁。
请查看以下代码:
import React from "react";
import { useForm } from "react-hook-form";
import "./styles.css";
export default function App() {
const {
register,
handleSubmit,
formState: { errors }
} = useForm();
const onSubmit = (data) => {
console.log(data);
};
return (
<div className="App">
<form onSubmit={handleSubmit(onSubmit)}>
<div className="form-control">
<label>Email</label>
<input
type="text"
name="email"
{...register("email", {
required: "Email is required.",
pattern: {
value: /^[^@ ]+@[^@ ]+\.[^@ .]{2,}$/,
message: "Email is not valid."
}
})}
/>
{errors.email && <p className="errorMsg">{errors.email.message}</p>}
</div>
<div className="form-control">
<label>Password</label>
<input
type="password"
name="password"
{...register("password", {
required: "Password is required.",
minLength: {
value: 6,
message: "Password should be at-least 6 characters."
}
})}
/>
{errors.password && (
<p className="errorMsg">{errors.password.message}</p>
)}
</div>
<div className="form-control">
<label></label>
<button type="submit">Login</button>
</div>
</form>
</div>
);
}
在上面的代码中,我们更改了电子邮件和密码验证代码。
对于电子邮件输入字段,我们修改了之前的代码:
{...register("email", {
required: true,
pattern: /^[^@ ]+@[^@ ]+\.[^@ .]{2,}$/
})}
修改以下代码:
{...register("email", {
required: "Email is required.",
pattern: {
value: /^[^@ ]+@[^@ ]+\.[^@ .]{2,}$/,
message: "Email is not valid."
}
})}
在这里,我们在添加验证功能的同时,直接提供了我们想要显示的错误消息。
因此,我们不再需要为每个验证添加额外的检查。我们使用对象message内部提供的属性errors来显示每个输入字段的错误信息,如下所示:
{errors.email && <p className="errorMsg">{errors.email.message}</p>}
这样一来,代码就得到了进一步简化,便于将来添加额外的验证。
请注意,如果存在验证错误,则不会执行 onSubmit 处理程序,并且相应的输入字段将自动获得焦点(这是一件好事)。
这是更新后的代码沙盒演示。
如何添加多个验证
您甚至可以通过添加对象为输入字段提供多重验证validate。如果您需要执行类似这样的复杂验证,这将非常有用:
<input
type="password"
name="password"
{...register("password", {
required: true,
validate: {
checkLength: (value) => value.length >= 6,
matchPattern: (value) =>
/(?=.*\d)(?=.*[a-z])(?=.*[A-Z])(?!.*\s)(?=.*[!@#$*])/.test(
value
)
}
})}
/>
要显示错误信息,我们这样使用它:
{errors.password?.type === "required" && (
<p className="errorMsg">Password is required.</p>
)}
{errors.password?.type === "checkLength" && (
<p className="errorMsg">
Password should be at-least 6 characters.
</p>
)}
{errors.password?.type === "matchPattern" && (
<p className="errorMsg">
Password should contain at least one uppercase letter, lowercase
letter, digit, and special symbol.
</p>
)}
这是一个代码沙盒演示。
如何重置表单值
有时,在执行某些操作后,我们需要重置/清除用户输入的数据。
例如,表单提交后,我们希望显示成功消息,然后清除表单数据,这样用户就不会重新提交相同的数据。
在这种情况下,我们可以调用reset钩子返回的函数useForm来清除表单数据。
const { reset } = useForm();
这是一个代码沙盒演示。
该reset函数还接受一个可选对象,您可以在其中传递要重置表单数据的值:
reset({
username: "Alex",
email: "alex@example.com",
password: "Test@123"
});
username这里,键email应该password与传递给函数的名称匹配register,以便相应的输入字段将被设置为传递的值。
如何使用默认值设置表单初始值
该useForm钩子接受一个选项列表,其中一个选项是defaultValues。
我们可以这样defaultValues为表单元素设置初始值,并在页面切换时重新设置它们:
const { user } = props;
const {
register,
handleSubmit,
formState: { errors }
} = useForm({
defaultValues: {
first_name: user.first_name,
last_name: user.last_name
}
});
// JSX
<Form.Control
type="text"
{...register("first_name")}
/>
<Form.Control
type="text"
{...register("last_name")}
/>
在上面的代码中,register我们为函数传递了first_name名称。这意味着defaultValues我们在设置初始值时使用了相同的名称。
因此,要正确设置输入值,您需要使用register与设置初始值函数中相同的名称defaultValues。
这是一个代码沙盒演示。
如何将 react-hook-form 与其他库一起使用
有时,我们可能会使用一些外部库,例如react-select,以允许在下拉菜单中进行多项选择。
在这种情况下,我们无法直接添加register显示下拉选择框的功能。因此,如果我们想react-hook-form在不编写自定义代码和处理函数的情况下添加验证,可以使用Controller组件,react-hook-form如下所示:
import React from "react";
import { useForm, Controller } from "react-hook-form";
import Select from "react-select";
import "./styles.css";
const departments = [
{ value: "Computer-Science", label: "Computer Science" },
{ value: "Physics", label: "Physics" },
{ value: "Chemistry", label: "Chemistry" },
{ value: "Mathematics", label: "Mathematics" }
];
export default function App() {
const {
control,
handleSubmit,
formState: { errors }
} = useForm();
const onSubmit = (data) => {
console.log(data);
};
return (
<div className="App">
<form onSubmit={handleSubmit(onSubmit)}>
<div className="form-control">
<label>Select Department of Interest</label>
<Controller
name="department"
control={control}
rules={{ required: true }}
render={({ field }) => (
<Select {...field} isMulti options={departments} />
)}
/>
{errors.department && (
<p className="errorMsg">This is a required field.</p>
)}
</div>
<div className="form-control">
<label></label>
<button type="submit">Submit</button>
</div>
</form>
</div>
);
}
这是一个代码沙盒演示。
如上面的代码所示,我们Controller在顶部导入了组件:
import { useForm, Controller } from "react-hook-form";
以及control像useForm这样的钩子:
const {
control,
handleSubmit,
formState: { errors }
} = useForm();
注意,我们register这里并没有使用该函数。
使用该react-select库实现多选功能的常规方法如下:
import Select from "react-select";
// use
<Select isMulti options={options} />
但是要使用它,react-hook-form我们需要将其包装在Controller组件中:
<Controller
name="department"
control={control}
rules={{ required: true }}
render={({ field }) => (
<Select {...field} isMulti options={options} />
)}
/>
这里,我们必须为nameprop提供一个唯一的值Controller。
验证规则作为 prop 的一部分添加rules,我们使用该renderprop 来渲染Select下拉菜单。
如何在 react-hook-form 中使用其他输入类型
在本节中,我们将学习如何使用单选按钮和复选框react-hook-form。
请查看以下代码:
import React from "react";
import { Button, Form } from "react-bootstrap";
import { useForm } from "react-hook-form";
import "./styles.css";
export default function App() {
const {
register,
handleSubmit,
formState: { errors }
} = useForm();
const onSubmit = (data) => {
console.log(data);
};
return (
<div className="container">
<form onSubmit={handleSubmit(onSubmit)}>
<Form.Group className="mb-3" controlId="email">
<Form.Label>Email</Form.Label>
<Form.Control
type="email"
placeholder="Enter your email"
{...register("email", {
required: "Please enter your email",
pattern: {
value: /^[^@ ]+@[^@ ]+\.[^@ .]{2,}$/,
message: "Please enter a valid email"
}
})}
/>
{errors.email && <p className="errorMsg">{errors.email.message}</p>}
</Form.Group>
<Form.Group className="mb-3" controlId="gender">
<Form.Label>Select Gender</Form.Label>
<Form.Check
type="radio"
label="Male"
value="male"
{...register("gender", {
required: "Please select your gender"
})}
/>
<Form.Check
type="radio"
label="Female"
value="female"
{...register("gender")}
/>
{errors.gender && <p className="errorMsg">{errors.gender.message}</p>}
</Form.Group>
<Form.Group className="mb-3" controlId="skills">
<Form.Label>Select Your Skills</Form.Label>
<Form.Check
type="checkbox"
label="JavaScript"
value="JavaScript"
{...register("skills", {
required: "Please select at-least one skill"
})}
/>
<Form.Check
type="checkbox"
label="React"
value="react"
{...register("skills")}
/>
<Form.Check
type="checkbox"
label="Node.js"
value="nodejs"
{...register("skills")}
/>
<Form.Check
type="checkbox"
label="Angular"
value="angular"
{...register("skills")}
/>
{errors.skills && <p className="errorMsg">{errors.skills.message}</p>}
</Form.Group>
<label></label>
<Button type="submit" variant="primary">
Submit
</Button>
</form>
</div>
);
}
这是一个代码沙盒演示。
在上面的代码中,我使用了react-bootstrap来使 UI 看起来更好,所以它Form.Check是一个react-bootstrap组件。
你需要记住的关键一点是,我们没有给register一组单选按钮和复选框使用相同的功能名称,例如:
<Form.Check
type="radio"
label="Male"
value="male"
{...register("gender", {
required: "Please select your gender"
})}
/>
<Form.Check
type="radio"
label="Female"
value="female"
{...register("gender")}
/>
在上面的代码中,我们将gender单选按钮命名为“”,并将skills所有复选框命名为“”,如下所示:
<Form.Check
type="checkbox"
label="JavaScript"
value="JavaScript"
{...register("skills", {
required: "Please select at-least one skill"
})}
/>
<Form.Check
type="checkbox"
label="React"
value="react"
{...register("skills")}
/>
<Form.Check
type="checkbox"
label="Node.js"
value="nodejs"
{...register("skills")}
/>
<Form.Check
type="checkbox"
label="Angular"
value="angular"
{...register("skills")}
/>
另外,请注意,必填字段验证仅针对第一个单选按钮或复选框添加。由于我们使用了相同的名称,因此无需为每个单选按钮或复选框添加相同的验证。
如何设置单选按钮和复选框的初始值
有时我们可能需要在页面加载时显示预先选择的单选按钮或复选框,在这种情况下,我们可以再次使用defaultValues钩子的选项useForm。
请查看以下代码:
import React from "react";
import { Button, Form } from "react-bootstrap";
import { useForm } from "react-hook-form";
import "./styles.css";
const initialValues = {
gender: "male",
skills: {
JavaScript: true,
react: false,
nodejs: true,
angular: false
}
};
export default function App() {
const {
register,
handleSubmit,
formState: { errors }
} = useForm({
defaultValues: {
gender: initialValues.gender,
skills: Object.keys(initialValues.skills).filter(
(item) => initialValues.skills[item] === true
)
}
});
const onSubmit = (data) => {
console.log(data);
};
return (
<div className="container">
<form onSubmit={handleSubmit(onSubmit)}>
<Form.Group className="mb-3" controlId="email">
<Form.Label>Email</Form.Label>
<Form.Control
type="email"
placeholder="Enter your email"
{...register("email", {
required: "Please enter your email",
pattern: {
value: /^[^@ ]+@[^@ ]+\.[^@ .]{2,}$/,
message: "Please enter a valid email"
}
})}
/>
{errors.email && <p className="errorMsg">{errors.email.message}</p>}
</Form.Group>
<Form.Group className="mb-3" controlId="gender">
<Form.Label>Select Gender</Form.Label>
<Form.Check
type="radio"
label="Male"
value="male"
{...register("gender", {
required: "Please select your gender"
})}
/>
<Form.Check
type="radio"
label="Female"
value="female"
{...register("gender")}
/>
{errors.gender && <p className="errorMsg">{errors.gender.message}</p>}
</Form.Group>
<Form.Group className="mb-3" controlId="skills">
<Form.Label>Select Your Skills</Form.Label>
<Form.Check
type="checkbox"
label="JavaScript"
value="JavaScript"
{...register("skills", {
required: "Please select at-least one skill"
})}
/>
<Form.Check
type="checkbox"
label="React"
value="react"
{...register("skills")}
/>
<Form.Check
type="checkbox"
label="Node.js"
value="nodejs"
{...register("skills")}
/>
<Form.Check
type="checkbox"
label="Angular"
value="angular"
{...register("skills")}
/>
{errors.skills && <p className="errorMsg">{errors.skills.message}</p>}
</Form.Group>
<label></label>
<Button type="submit" variant="primary">
Submit
</Button>
</form>
</div>
);
}
这是一个代码沙盒演示。
上面的代码中,我们有一个initialValues对象,其中包含我们希望在页面初始加载时设置的值:
const initialValues = {
gender: "male",
skills: {
JavaScript: true,
react: false,
nodejs: true,
angular: false
}
};
由于我们可以拥有多种技能,因此技能skills是一个对象,如上所示。所以,我们希望显示选中的单选按钮(如果其值为“男性”),并且我们只想显示选中的、其值true在对象中的复选框skills。
因此,对于该选项,我们使用该方法defaultValues遍历对象,以找出值如下所示的选项:skillsfilterskillstrue
const {
register,
handleSubmit,
formState: { errors }
} = useForm({
defaultValues: {
gender: initialValues.gender,
skills: Object.keys(initialValues.skills).filter(
(item) => initialValues.skills[item] === true
)
}
});
由于 ` JavaScriptand` 的nodejs值是 `is` true,因此方法skills后的数组filter将变为`is` ["JavaScript", "nodejs"],所以defaultValues对象将如下所示:
useForm({
defaultValues: {
gender: 'male',
skills: ["JavaScript", "nodejs"]
}
});
因此,当页面加载时,默认情况下只会选择/勾选male性别和JavaScript技能。Node.js
请注意,对象中使用的大小写必须与复选框指定的skills大小写一致。value
所以即使复选框的标签是Node.js,它的值也是,nodejs所以我们使用nodejs作为对象中的键initialValues。
下面展示的是页面加载时的效果演示。
就这样!你已经学会了如何使用 react-hook-form 在 React 中更轻松地构建复杂的表单。
感谢阅读!
如果你想从零开始详细学习 Redux,并构建 3 个应用程序以及完整的食品订购应用程序,请查看我的Redux 精通课程。
在本课程中,您将学习到:
- Redux 基础与进阶
- 如何管理数组和对象的复杂状态
- 如何使用多个 reducer 来管理复杂的 Redux 状态
- 如何调试 Redux 应用
- 如何在 React 中使用 Redux,并使用 react-redux 库使你的应用程序具有响应式特性。
- 如何使用 redux-thunk 库处理异步 API 调用
- 使用 Redux 构建 3 个不同的应用程序
还有更多。
最后,我们将从零开始构建一个完整的食品订购应用程序,集成 Stripe 以接受付款,并将其部署到生产环境中。
想及时获取有关 JavaScript、React 和 Node.js 的最新内容吗?请在 LinkedIn 上关注我。
文章来源:https://dev.to/myogeshchavan97/best-library-to-create-simple-and-complex-forms-in-react-k73








