我正在使用Formik / Yup来验证页面,该页面称为GraphQL突变。我的代码可以正常工作:
export default function RemoveUserPage() {
const [isSubmitted, setIsSubmitted] = useState(false);
const [isRemoved ,setIsRemoved] = useState(false);
const [errorMessage, setErrorMessage] = useState('');
const [removeUser] = useMutation(RemoveUserMutation);
function submitForm(email: string) {
setIsSubmitted(true);
removeUser({
variables: {
email: email,
},
}).then(({ data }: any) => {
setIsRemoved(true);
console.log('info: ', data.deleteUser);
})
.catch((error: { message: string; }) => {
setIsRemoved(false);
console.log("Error msg:" + error.message);
setErrorMessage(error.message)
})
}
return (
<div>
<PermanentDrawerLeft></PermanentDrawerLeft>
<Formik
initialValues={{ email: '' }}
onSubmit={(values, actions) => {
setTimeout(() => {
alert(JSON.stringify(values, null, 2));
actions.setSubmitting(false);
}, 1000);
}}
validationSchema={schema}
>
{props => {
const {
values: { email },
errors,
touched,
handleChange,
isValid,
setFieldTouched
} = props;
const change = (name: string, e: any) => {
e.persist();
handleChange(e);
setFieldTouched(name, true, false);
};
return (
<div className='main-content'>
<form style={{ width: '100%' }}
onSubmit={e => {e.preventDefault();submitForm(email)
}}>
<div>
<TextField
variant="outlined"
margin="normal"
id="email"
name="email"
helperText={touched.email ? errors.email : ""}
error={touched.email && Boolean(errors.email)}
label="Email"
value={email}
onChange={change.bind(null, "email")}
/>
<br></br>
<Button
type="submit"
disabled={!isValid || !email}
>
Remove User</Button>
</div>
</form>
<br></br>
{isSubmitted && StatusMessage(isRemoved, errorMessage)}
</div>
)
}}
</Formik>
</div>
);
}
但是,现在我想使用useFormik
钩子而不是<Formik>
,但是我不能这样做。我已经看到了以下示例,但由于我使用的是材料ui组件而不是特定于甲酸的输入,因此我无法弄清楚在我的情况下如何在语法上精确地使用它。
https://jaredpalmer.com/formik/docs/api/useFormik
编辑:
这将进行编译,但在文本字段上没有进行任何验证。我想念什么?
export const schema = Yup.object({
email: Yup.string()
.email('Invalid Email')
.required('This Field is Required'),
});
export default function RemoveUserPage() {
const [isSubmitted, setIsSubmitted] = useState(false);
const [isRemoved, setIsRemoved] = useState(false);
const [errorMessage, setErrorMessage] = useState('');
const [removeUser] = useMutation<DeleteUserResponse>(REMOVE_USER);
let submitForm = (email: string) => {
setIsSubmitted(true);
removeUser({
variables: {
email: email,
},
})
.then(({ data }: ExecutionResult<DeleteUserResponse>) => {
if (data !== null && data !== undefined) {
setIsRemoved(true);
console.log('info: ', data.deleteUser);
}
})
.catch((error: { message: string }) => {
setIsRemoved(false);
console.log('Error msg:' + error.message);
setErrorMessage(error.message);
});
};
const formik = useFormik({
initialValues:{ email: '' },
onSubmit:(values, actions) => {
setTimeout(() => {
alert(JSON.stringify(values, null, 2));
actions.setSubmitting(false);
}, 1000);
},
validationSchema:{schema}
})
const handleChange = (e: ChangeEvent<HTMLInputElement>)=>{
const {name,value} = e.target;
formik.setFieldValue(name,value);
}
return (
<div>
<PermanentDrawerLeft></PermanentDrawerLeft>
<Wrapper>
<Form
onSubmit={e => {
e.preventDefault();
submitForm(formik.values.email);
}}>
<div>
<TextField
variant="outlined"
margin="normal"
id="email"
name="email"
helperText={formik.touched.email ? formik.errors.email : ''}
error={formik.touched.email && Boolean(formik.errors.email)}
label="Email"
value={formik.values.email}
//onChange={change.bind(null, 'email')}
onChange={handleChange}
/>
<br></br>
<CustomButton
disabled={!formik.values.email}
text={'Remove User'}
/>
</div>
</Form>
<br></br>
{isSubmitted && StatusMessage(isRemoved, errorMessage)}
</Wrapper>
</div>
);
}
它给了我这个错误:
TypeError: schema[sync ? 'validateSync' : 'validate'] is not a function. (In 'schema[sync ? 'validateSync' : 'validate'](validateData, {
abortEarly: false,
context: context
})', 'schema[sync ? 'validateSync' : 'validate']' is undefined)
第二,早些时候,我在按钮上使用了isValid
,但现在出现了错误。有其他选择吗?
答案 0 :(得分:1)
更新时间:2020年8月20日
我认为在文档中再次强调了这一点,该文档不适合一般用例。
请使用Computation failed in `stat_function()`:
object '.meanNDVI' not found
而不是挂钩。
作者的评论:Jared Palmer本人。
我在这里标记了一些问题:
https://github.com/formium/formik/issues/1722#issue-475725015 https://github.com/formium/formik/pull/1717#issuecomment-516867884
就像乔·霍金斯(Jow Hawkins)提到的那样,了解钩子将是非常困难的,但是我将为您提供一些更改和答案,以帮助您开始使用钩子。
<Formik>
编辑:
由于您正在使用Material Ui文本字段
添加export default function RemoveUserPage() {
const [isSubmitted, setIsSubmitted] = useState(false);
const [isRemoved ,setIsRemoved] = useState(false);
const [errorMessage, setErrorMessage] = useState('');
const [removeUser] = useMutation(RemoveUserMutation);
function submitForm(email: string) {
setIsSubmitted(true);
removeUser({
variables: {
email: email,
},
}).then(({ data }: any) => {
setIsRemoved(true);
console.log('info: ', data.deleteUser);
})
.catch((error: { message: string; }) => {
setIsRemoved(false);
console.log("Error msg:" + error.message);
setErrorMessage(error.message)
})
}
const formik = useFormik({
initialValues:{ email: '' },
onSubmit:(values, actions) => {
setTimeout(() => {
alert(JSON.stringify(values, null, 2));
actions.setSubmitting(false);
}, 1000);
},
validationSchema:schema
})
// depend on the return value
const handleSubmit = (someReturnValue or event)=>{
// if the return event has name
// such as event.target.name then you got the name
// and try event.target.value
// then set field value
// eg: const value = event.current.value
formik.setFieldValue(name, value)
}
// dont forget to set onBlur as well
// this i will leave it to you
return (
<div>
<PermanentDrawerLeft></PermanentDrawerLeft>
<div className='main-content'>
<form style={{ width: '100%' }}
onSubmit={formik.handleSubmit}>
<div>
<TextField
variant="outlined"
margin="normal"
id="email"
name="email"
helperText={formik.touched.email ? formik.errors.email : ""}
error={formik.touched.email && Boolean(formik.errors.email)}
label="Email"
value={formik.values.email}
onChange={handleChange}
/>
<br></br>
<Button
type="submit"
disabled={!isValid || !email}
>
Remove User</Button>
</div>
</form>
<br></br>
{isSubmitted && StatusMessage(isRemoved, errorMessage)}
</div>
</div>
);
}
方法
handleChange
然后在您的电子邮件组件中
const handleChange = (event)=>{
// get name and value from event.target
// is the same as const name = event.target.name
const {name,value} = event.target
// make sure you have name prop in
// your textfield and it is same name as your initial state
formik.setFieldValue(name,value) // this call formik to set your value
}