gpt4 book ai didi

javascript - 防止在路线更改时提交 Formik AutoSave

转载 作者:行者123 更新时间:2023-12-03 13:35:17 25 4
gpt4 key购买 nike

我的应用程序的表单为 <AutoSave/> 成分。一旦表单值发生更改,该组件就会调用提交。一切正常,但是当更改路线时,它会更改表单值和 <AutoSave/>调用提交。如何解决这个问题呢?一个可能的解决方案是安装 <AutoSave/>改变路线时再次。

Codesandbox

自动保存:

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>
)

最佳答案

查看一下:https://codesandbox.io/s/clever-sun-057vy

# Problem

useEffect(() => debouncedSubmit, [debouncedSubmit, formik.values]);
即使组件安装后,

formik.values 也始终会发生变化。这就是为什么 debouncedSubmit 在路由更改时被调用。

所以基本上,我们不想将其作为组件首次渲染运行,而是在用户更改表单时运行。

formik.dirty 是关键。只需在提交之前检查 formik.dirty 即可。

const AutoSave = ({ debounceMs }) => {
const formik = useFormikContext();

const debouncedSubmit = useCallback(
debounce(formik.submitForm, debounceMs),
[formik.submitForm, debounceMs]
);

useEffect(() => {
formik.dirty && debouncedSubmit();
}, [debouncedSubmit, formik.dirty, formik.values]);

return <>{!!formik.isSubmitting && 'saving...'}</>;
};

另一件事是 Formik 实例。这个 Formik 将用于所有书籍。因此,在将新书绑定(bind)到表单中时,您需要使用 enableReinitialize prop 重置表单。 .

<Formik
enableReinitialize
initialValues={{ title: book.title, summary: book.summary, id: book.id }}
onSubmit={values => handleSubmit(values)}
>

或者为每本书使用单独的实例 key={book.id}

<Formik
key={book.id}
initialValues={{ title: book.title, summary: book.summary, id: book.id }}
onSubmit={values => handleSubmit(values)}
>

关于javascript - 防止在路线更改时提交 Formik AutoSave,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59285019/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com