onReset causes RangeError: Maximum call stack size exceeded
onReset causes RangeError: Maximum call stack size exceeded
在我的 React Redux 应用程序中,我使用 react-bootstrap(v^1.6.0) 和 Formik(v2.2.6) 构建过滤器表单。
除重置处理外一切正常。单击重置按钮后,我得到
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 store
有人理解这种行为吗?谢谢!
您似乎创建了一个无限循环:
- 点击重置
- 触发 Formik
onReset
,调用 onResetAction
onResetAction
呼叫 helper.resetForm()
- ...强制重置表单,
- 哪个触发了 Formik
onReset
和你身边永远
要修复它,请不要从 onReset
调用 resetForm
。如果你想连接一个重置按钮,你可以直接将你的 onResetAction
挂接到普通(即不是 'reset')按钮的 onClick
处理程序。
在我的 React Redux 应用程序中,我使用 react-bootstrap(v^1.6.0) 和 Formik(v2.2.6) 构建过滤器表单。
除重置处理外一切正常。单击重置按钮后,我得到
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 store
有人理解这种行为吗?谢谢!
您似乎创建了一个无限循环:
- 点击重置
- 触发 Formik
onReset
,调用onResetAction
onResetAction
呼叫helper.resetForm()
- ...强制重置表单,
- 哪个触发了 Formik
onReset
和你身边永远
要修复它,请不要从 onReset
调用 resetForm
。如果你想连接一个重置按钮,你可以直接将你的 onResetAction
挂接到普通(即不是 'reset')按钮的 onClick
处理程序。