在我的React Redux应用程序中,我使用带有Formik(v2.2.6(的React bootstrap(v^1.6.0(来构建过滤器表单。
除了重置处理外,一切都很好。点击重置按钮后,我得到
RangeError: Maximum call stack size exceeded
resetForm
src/Formik.tsx:347
344 | }
345 | }, [validateOnMount, validateFormWithHighPriority]);
346 |
> 347 | const resetForm = React.useCallback(
| ^ 348 | (nextState?: Partial<FormikState<Values>>) => {
349 | const values =
350 | nextState && nextState.values
View compiled
onResetAction [as onReset]
src/use-cases/schools-page/declarations-page/components/DeclarationsFilter.tsx:42
39 | }
40 |
41 | const onResetAction = (values: FilterValues, helpers: FormikHelpers<FilterValues>) => {
> 42 | helpers.resetForm()
| ^ 43 | onFilterChange({})
44 | }
45 |
下方的我的代码
import React from 'react'
import { Declaration } from 'store/declarations/reducer'
import { DeclarationsFilters } from 'use-cases/schools-page/declarations-page/types'
import { Button, Col, Form } from 'react-bootstrap'
import { uniq } from 'lodash'
import { Formik, FormikHelpers } from 'formik'
type Props = {
filters: DeclarationsFilters
allDeclarations: Declaration[]
onFilterChange: (filters: DeclarationsFilters) => void
}
type FilterValues = {
surname: string
classNumber: string
className: string
}
const all = 'wszystkie'
export const DeclarationsFilter: React.FC<Props> = ({ filters, allDeclarations, onFilterChange }): JSX.Element => {
const allClasses = uniq(allDeclarations.map((declaration) => declaration.classNumber))
const allClassNames = uniq(allDeclarations.map((declaration) => declaration.className))
const onSearch = (values: FilterValues, helpers: FormikHelpers<FilterValues>) => {
helpers.setSubmitting(true)
const changedFilters: DeclarationsFilters = {
surname: values.surname,
selectedClass: values.classNumber === all ? undefined : parseInt(values.classNumber, 10),
selectedClassName: values.className === all ? undefined : values.className
}
onFilterChange(changedFilters)
helpers.setSubmitting(false)
}
const onResetAction = (values: FilterValues, helpers: FormikHelpers<FilterValues>) => {
helpers.resetForm()
onFilterChange({})
}
return (
<Formik
initialValues={{
classNumber: filters.selectedClass?.toString() || all,
className: filters.selectedClassName || all,
surname: filters.surname || ''
}}
onSubmit={onSearch}
onReset={onResetAction}
>
{({ handleSubmit, isSubmitting, handleChange, handleBlur, values, handleReset }) => (
<Form noValidate onSubmit={handleSubmit} onReset={handleReset}>
<Form.Row>
<Col>
<Form.Group controlId="declarationsFilter.surname">
<Form.Label>Nazwisko</Form.Label>
<Form.Control
type="text"
placeholder="..."
onBlur={handleBlur}
name="surname"
onChange={handleChange}
value={values.surname}
/>
</Form.Group>
</Col>
<Col>
<Form.Group controlId="declarationsFilter.classNumber">
<Form.Label>Klasa:</Form.Label>
<Form.Control
as="select"
onBlur={handleBlur}
name="classNumber"
onChange={handleChange}
value={values.classNumber}
>
<option>{all}</option>
{allClasses.map((classNumber) => (
<option>{classNumber}</option>
))}
</Form.Control>
</Form.Group>
</Col>
<Col>
<Form.Group controlId="declarationsFilter.className">
<Form.Label>Nazwa klasy:</Form.Label>
<Form.Control
as="select"
onBlur={handleBlur}
name="className"
onChange={handleChange}
value={values.className}
>
<option>{all}</option>
{allClassNames.map((classNumber) => (
<option>{classNumber}</option>
))}
</Form.Control>
</Form.Group>
</Col>
</Form.Row>
<Form.Row>
<Button variant="primary" type="submit" disabled={isSubmitting}>
Filtruj
</Button>
<Button variant="primary" type="reset">
Resetuj
</Button>
</Form.Row>
</Form>
)}
</Formik>
)
}
方法"onFilterChange"目前不执行任何操作。它将在未来更新redux存储。
有人理解这种行为吗?谢谢
看起来你已经创建了一个无限循环:
- 单击重置
- 触发器Formik
onReset
,调用onResetAction
onResetAction
调用helper.resetForm()
- 。。。强制重置表单
- 是什么触发了Formik
onReset
和你周围的一切
若要修复此问题,请不要从onReset
调用resetForm
。如果你想连接一个重置按钮,你可以直接将onResetAction
挂接到普通(即不是"重置"(按钮的onClick
处理程序上。