我正在编写一个React应用程序,并使用Formik和Yup来处理表单。我遇到的问题是一个向导风格的页面,它在页面加载时呈现Form 1,上面有一个“Next”按钮。按下“Next”会呈现Form 2,“Back”和“Next”按钮会与Form 2一起出现,这会让你通过向导。
麻烦的是使用返回按钮。在我完成填写Form 1后,“Next”按钮变为启用,我可以移动到下一个表单。当我在Form 2上时,我希望能够返回Form 1并按下“Back”按钮。当重新呈现Formik时,它会将值正确加载到表单中,但它不会验证表单,因此“Next”按钮被禁用,即使数据是有效的。我必须在其中一个字段上引起一个更改事件才能启用“下一步”按钮。
在这种情况下,当表单重新呈现时,“Next”按钮应该被启用。我已经看过文档并尝试了Formik中的validateOnMount prop,根据它的名称应该可以工作。文档建议使用initialErrors,但我不清楚如何使用它。问题也可能是我如何启用/禁用“Next”按钮。
这让我抓狂了好几个小时,这是我在周五下午完成这一页的最后一件事。
<Formik
enableReinitialize
validationSchema={validationSchema}
initialValues={initialValues}
validateOnMount
render={({ isValid, values, isSubmitting, handleChange, setFieldValue, setFieldTouched }) => (
<Form className="text-center">
<FieldRow labelName="What's your address? (Can't be a PO Box)">
<AddressField
id="address"
name="address"
data-testid="address"
onChange={handleChange}
onBlur={setFieldTouched}
values={values}
setFieldValue={setFieldValue}
validateForm={validateForm}
/> </FieldRow>
<div className="mt-5">
<Button
data-testid="submit-next"
color="primary"
onClick={() => handleNext(values)}
className="float-right"
disabled={isValid === false || isSubmitting}
>
{isSubmitting ? <Spinner /> : 'Next'}
</Button>
<Button
data-testid="submit-back"
color="light"
onClick={() => handleBack()}
className="float-left"
disabled={true}
>
Back
</Button>
</div>
</Form>
)}
/>
字符串
3条答案
按热度按时间0s0u357o1#
这不起作用的原因是因为当你第一次进入该页面时,
Formik
组件被挂载并呈现。然后,当你按下下一步或后退时,它不会再次挂载,它只是更新了,所以它不会再次触发验证。如果你有back和next按钮,我假设你使用它们来递增
index
或step
变量/状态。你可以做的是从step
状态为deps
的useEffect
手动触发验证调用validateForm()
。为了做到这一点,你必须用
<Formik component={...} />
或useFormik
替换<Formik render={...} />
,因为你不能在回调函数中使用useEffect
,正如注解中指出的那样。使用第二种选择:字符串
或者,您可以尝试使用
initialErrors
,但这可能会在实际上不需要这样做时触发验证,如果除了step
之外还有其他可能导致重新渲染的东西:型
此外,看起来当前有一个相关的bug打开,建议的临时修复也使用
useEffect
,所以即使你使用initialErrors
,你可能仍然需要添加useEffect
,直到这个问题得到解决:https://github.com/jaredpalmer/formik/issues/1950的
brtdzjyr2#
我发现一个避免运行useEffect onMount的简单方法是在表单中使用onFocus prop。例如:
字符串
如果表单中有多个输入,只需向每个输入添加相同的
onFocus={() => setHasFocused(true)
。让我知道如果你有任何问题:)
wb1gzix03#
我相信在装载时进行验证并获得'isValid'的正确值的正确方法是,这对我很有效
字符串