【发布时间】:2020-04-04 16:33:25
【问题描述】:
我的应用程序的表单带有 <AutoSave/> 组件。一旦表单值改变,这个组件就会调用提交。一切正常,但是当更改路由时,它会更改表单值和<AutoSave/> 调用提交。如何解决这个问题呢?一个可能的解决方案是在更改路由时再次挂载<AutoSave/>。
自动保存:
import React, { useEffect, useCallback } from 'react'
import { useFormikContext } from 'formik'
import debounce from 'lodash.debounce'
const AutoSave = ({ debounceMs }) => {
const formik = useFormikContext()
const debouncedSubmit = useCallback(
debounce(formik.submitForm, debounceMs),
[formik.submitForm, debounceMs]
)
useEffect(() => debouncedSubmit, [debouncedSubmit, formik.values])
return <>{!!formik.isSubmitting && "saving..."}</>
}
我的应用:
const App: FC = () => {
const {books} = getBooks() // [{id: 1, title: 'test', summary: 'test'}, ...]
const {query} = useRouter()
const handleSubmit = useCallback(async values => {
try {
await API.patch('/books', {id: query.book, ...values})
} catch (e) {}
}, [query.book])
return (
<>
<span>Books</span>
{books.map(({id, title}, key) => (
<Link key={key} href='/book/[book]' as={`/book/${id}`}>
<a>{title}</a>
</Link>
))}
{query.book && (
<MainForm
book={books.find(book => book.id === query.book)}
handleSubmit={handleSubmit}/>
)}
</>
)
}
主窗体:
type Props = {
book: BookProps // {id: string, title: string ...},
handleSubmit: (values) => Promise<void>
}
const MainForm: FC<Props> = ({book, handleSubmit}) => (
<Formik
enableReinitialize
initialValues={{title: book.title, summary: book.summary}}
handleSubmit={values => handleSubmit(values)}>
{() => (
<Form>
//...My fields...
<AutoSave debounceMs={500}/> // <=== AutoSave with debounce
</Form>
)}
</Formik>
)
【问题讨论】:
-
也许您可以尝试在您的 formik 道具上使用
enableReinitialize = true获取表单值。由于您的组件顶部有状态,因此它会因新值而重新呈现。 -
@Lhew,嗨!我在表单中添加了
enableReinitialize,但这不是解决这个问题的关键。也许我需要比较上一个和下一个查询bookid,然后再次挂载 AutoSave
标签: javascript reactjs react-hooks next.js formik