请参阅下面的更新
我有一个使用Formik构建的,与Firebase身份验证同步的登录表单组件。我进行了设置,以便可以使用setFieldError
道具显示Firebase中的错误。这是代码的相关部分:
export const LoginForm = () => {
async function authenticateUser(values, setFieldError) {
const { email, password } = values
try {
await firebase.login(email, password)
navigate('/', { replace: true })
} catch (error) {
console.log('Authentication Error: ', error)
await setFieldError('firebaseErrorMessage', error.message)
}
}
return (
<>
<h1>Form</h1>
<Formik
render={props => <RenderForm {...props} />}
initialValues={initialValues}
validationSchema={validationSchema}
onSubmit={async (
values,
{ setFieldError, setSubmitting, resetForm }
) => {
setSubmitting(true)
authenticateUser(values, setFieldError)
setSubmitting(false)
resetForm()
}}
/>
</>
)
}
const RenderForm = ({ errors, isSubmitting, isValid }) => (
<Form>
<h3>Sign Up</h3>
<Email name="email" />
<Password name="password" />
<Button disabled={!isValid || isSubmitting} type="submit">
Submit
</Button>
{errors.firebaseErrorMessage && <p>{errors.firebaseErrorMessage}</p>}
</Form>
)
现在,这很好。但是,如果我尝试使用Formik的ErrorMessage
组件显示错误消息,则该消息不会显示。
换句话说,这可行:
{errors.firebaseErrorMessage && <p>{errors.firebaseErrorMessage}</p>}
这不有效:
<ErrorMessage name="firebaseErrorMessage" />
有什么想法为什么不起作用以及如何使其起作用?
谢谢。
更新
这是我的初始值:
const initialValues = {
email: '',
password: '',
}
答案 0 :(得分:1)
我认为您不应该将Formik的错误用于Firebase错误。 Formik的错误旨在验证表单输入。要存储和引用API错误,我会useState
。
更新:您可以使用Formik的status
对象代替useState
。处理API错误是他为status
提供的示例。
我认为问题是在Formik中,name
是指输入的名称。相反,您必须使用errors
向setFieldError
对象添加一个新的name属性,但是firebaseErrorMessage
不是表单中的字段。 (共享您的initialValues
对象以进行验证。)
这有意义吗?其中一个令人讨厌的部分是,您可能无法直接利用与<ErrorMessage>
相关的某些样式。但是,我认为,正确构建系统的结构可能更重要,然后您可以根据需要模拟样式。
这是我的代码建议:
const RenderForm = ({ isSubmitting, isValid, status }) => (
<Form>
<h3>Sign Up</h3>
<Email name="email" />
<Password name="password" />
<Button disabled={!isValid || isSubmitting} type="submit">
Submit
</Button>
{status.firebaseErrorMessage && <p>{status.firebaseErrorMessage}</p>}
</Form>
);
export const LoginForm = () => {
async function authenticateUser(values, setStatus, setSubmitting) {
const { email, password } = values;
setSubmitting(true);
try {
await firebase.login(email, password);
navigate("/", { replace: true });
} catch (error) {
console.log("Authentication Error: ", error);
setStatus({
firebaseErrorMessage: error.message
});
} finally {
setSubmitting(false);
}
}
return (
<>
<h1>Form</h1>
<Formik
render={props => <RenderForm {...props} />}
initialValues={initialValues}
validationSchema={validationSchema}
onSubmit={async (values, { setStatus, setSubmitting, resetForm }) => {
await authenticateUser(values, setStatus, setSubmitting);
resetForm();
}}
/>
</>
);
};