Material ui 将YUP与物料UI文本字段一起使用
我正在尝试将表单转换为使用Material ui TextField。我如何让我的YUP验证与之一起工作?这是我的密码:Material ui 将YUP与物料UI文本字段一起使用,material-ui,rect,formik,yup,Material Ui,Rect,Formik,Yup,我正在尝试将表单转换为使用Material ui TextField。我如何让我的YUP验证与之一起工作?这是我的密码: import * as React from "react"; import { useState } from 'react'; import { Row, Col } from "react-bootstrap"; import TextField from '@material-ui/core/TextField'; import Button from '@mater
import * as React from "react";
import { useState } from 'react';
import { Row, Col } from "react-bootstrap";
import TextField from '@material-ui/core/TextField';
import Button from '@material-ui/core/Button';
import { Formik, Form, Field, ErrorMessage } from "formik";
import * as Yup from "yup";
import axios from "axios";
import Error from "../../Error";
type FormValues = {
username: string;
password: string;
repeatPassword: string;
fullName: string;
country: string;
email: string;
};
export default function CreatePrivateUserForm(props: any) {
const [errorMessage, setErrorMessage] = useState();
const createPrivateAccountSchema = Yup.object().shape({
username: Yup.string()
.required("Required")
.min(8, "Too Short!")
.max(20, "Too Long!")
.matches(/^[\w-.@ ]+$/, {
message: "Inccorect carector"
}),
password: Yup.string()
.required("Required")
.min(10, "Too Short!")
.max(100, "Too Long!")
.matches(/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[^a-zA-Z\d\s:]).*$/, {
message: "Password need to contain 1 uppercase character (A-Z), 1 lowercase character (a-z), 1 digit (0-9) and 1 special character (punctuation)"
}),
repeatPassword: Yup.string()
.required("Required")
.oneOf([Yup.ref("password")], "Passwords must match")
});
function handleSuccess() {
alert("User was created");
}
async function handleSubmit(values: FormValues) {
const token = await props.googleReCaptchaProps.executeRecaptcha("CreatePrivateUser");
const headers = {
headers: {
Accept: "application/json",
"Content-Type": "application/json",
recaptcha: token
}
};
const body = { username: values.username, password: values.password, repeatPassword: values.repeatPassword };
const url = "xxx";
try {
const response = await axios.post(url, body, headers);
if (response.status === 201) {
handleSuccess();
}
if (response.status === 400) {
console.log("Bad Request ...");
setErrorMessage('Bad Request');
} else if (response.status === 409) {
console.log("Conflict ...");
setErrorMessage('Conflict');
} else if (response.status === 422) {
console.log("Client Error ...");
setErrorMessage('Client Error');
} else if (response.status > 422) {
console.log("Something went wrong ...");
setErrorMessage('Something went wrong');
} else {
console.log("Server Error ...");
setErrorMessage('Server Error');
}
} catch (e) {
console.log("Fejl");
}
}
return (
<React.Fragment>
<Row>
<Col xs={12}>
<p>Please register by entering the required information.</p>
</Col>
</Row>
<Row>
<Col xs={12}>
<Formik
initialValues={{ username: "", password: "", repeatPassword: "" }}
validationSchema={createPrivateAccountSchema}
onSubmit={async (values, { setErrors, setSubmitting }) => {
await handleSubmit(values);
setSubmitting(false);
}}>
{({ isSubmitting }) => (
<Form>
{errorMessage ? <Error errorMessage={errorMessage} /> : null}
<Row>
<Col xs={6}>
<Row>
<Col xs={12}>
<TextField
label="Username"
helperText={touched.username ? errors.username : ""}
error={touched.username && Boolean(errors.username)}
type="text"
name="username"
margin="normal"
variant="filled"
/>
<ErrorMessage name='username'>{msg => <div className='error'>{msg}</div>}</ErrorMessage>
</Col>
</Row>
<Row>
<Col xs={12}>
<label htmlFor='password'>Password:</label>
<Field type='password' name='password' />
<ErrorMessage name='password'>{msg => <div className='error'>{msg}</div>}</ErrorMessage>
</Col>
</Row>
<Row>
<Col xs={12}>
<label htmlFor='repeatPassword'>Repeat password:</label>
<Field type='password' name='repeatPassword' />
<ErrorMessage name='repeatPassword'>{msg => <div className='error'>{msg}</div>}</ErrorMessage>
</Col>
</Row>
</Col>
</Row>
<Row>
<Col xs={12}>
<button type='submit' disabled={isSubmitting}>
Create User
</button>
</Col>
</Row>
</Form>
)}
</Formik>
</Col>
</Row>
</React.Fragment>
);
}
import*as React from“React”;
从“react”导入{useState};
从“react bootstrap”导入{Row,Col};
从“@material ui/core/TextField”导入TextField;
从“@material ui/core/Button”导入按钮;
从“Formik”导入{Formik,Form,Field,ErrorMessage};
从“Yup”导入*作为Yup;
从“axios”导入axios;
从“../../Error”导入错误;
类型FormValues={
用户名:字符串;
密码:字符串;
重复密码:字符串;
全名:字符串;
国家:字符串;
电子邮件:字符串;
};
导出默认函数CreatePrivateUserForm(props:any){
const[errorMessage,setErrorMessage]=useState();
const createPrivateAccountSchema=Yup.object().shape({
用户名:Yup.string()
.必需(“必需”)
.min(8,“太短!”)
.max(20,“太长了!”)
.matches(/^[\w-.@]+$/{
消息:“Inccorect管理员”
}),
密码:Yup.string()
.必需(“必需”)
.min(10,“太短了!”)
.max(100,“太长了!”)
.matches(/^(?=.[a-z])(?=.[a-z])(?=..*\d)(?=.[^a-zA-z\d\s:])。$/{
消息:“密码需要包含1个大写字符(A-Z)、1个小写字符(A-Z)、1个数字(0-9)和1个特殊字符(标点符号)”
}),
重复密码:Yup.string()
.必需(“必需”)
.oneOf([Yup.ref(“密码”)],“密码必须匹配”)
});
函数handleSuccess(){
警报(“用户已创建”);
}
异步函数handleSubmit(值:FormValues){
const-token=await-props.googlerepactchaprops.executecaptcha(“CreatePrivateUser”);
常量头={
标题:{
接受:“应用程序/json”,
“内容类型”:“应用程序/json”,
recaptcha:令牌
}
};
const body={username:values.username,password:values.password,repeatPassword:values.repeatPassword};
const url=“xxx”;
试一试{
const response=wait axios.post(url、正文、标题);
如果(response.status==201){
handleSuccess();
}
如果(response.status==400){
日志(“错误请求…”);
setErrorMessage(“错误请求”);
}else if(response.status==409){
console.log(“冲突…”);
setErrorMessage(“冲突”);
}else if(response.status==422){
日志(“客户端错误…”);
setErrorMessage(“客户端错误”);
}否则如果(response.status>422){
log(“出了点问题…”);
setErrorMessage(“出现了问题”);
}否则{
日志(“服务器错误…”);
setErrorMessage(“服务器错误”);
}
}捕获(e){
控制台日志(“Fejl”);
}
}
返回(
请输入所需信息进行注册
{
等待handleSubmit(值);
设置提交(假);
}}>
{({isSubmitting})=>(
{errorMessage?:null}
{msg=>{msg}
密码:
{msg=>{msg}
重复密码:
{msg=>{msg}
创建用户
)}
);
}
我能看到的第一件事是,您已经剥离了标准的formik
组件,并直接更改为
。根据fomik文档,
组件实际上是一个特殊组件,它“将自动将输入连接到Formik。它使用name属性与Formik状态匹配”。因此,我认为formik不再实际处理输入,而是不受控制的组件(没有react state设置值的html组件)。随着formik不再处理输入,Yup验证构建到formik中并通过schema prop使用,将无法正常工作
要解决此问题,您可以使用库(MaterialUI建议使用此库),也可以为formik创建自定义输入组件。这允许您将
的组件道具设置为一个组件,该组件可以正确地将材料UI与formik数据连接起来
公开
const CustomTextInput = ({
field, // { name, value, onChange, onBlur }
form: { touched, errors }, // also values, setXXXX, handleXXXX, dirty, isValid, status, etc.
...props
}) => (
<div>
<TextField
error={_.get(touched, field.name) && _.get(errors, field.name) && true}
helperText={_.get(touched, field.name) && _.get(errors, field.name)}
{...field}
{...props}
/>
</div>
)
const CustomTextInput=({
字段,//{name,value,onChange,onBlur}
表单:{toucted,errors},//还有值,setXXXX,handlexxx,dirty,isValid,status,等等。
…道具
}) => (
)
然后在你的状态下,你可以这样做
<Field
name="fieldName"
component={CustomTextInput}
label="You can use the Material UI props here to adjust the input"
/>
您可以在有关字段的formik文档中找到一个示例和更多信息-