【发布时间】:2020-10-22 12:18:22
【问题描述】:
如何使用 react-admin 实现自动保存/后台保存功能?
我在编辑富输入字段时想要一个功能,例如富文本,后台保存会将我的文本推送到服务器,而无需触摸我的焦点和编辑位置。
我尝试使用 EditController 和 SimpleFrom,这将重新渲染表单并从服务器获取记录器,并且失去焦点和编辑位置。 请问有什么例子或建议吗?
【问题讨论】:
如何使用 react-admin 实现自动保存/后台保存功能?
我在编辑富输入字段时想要一个功能,例如富文本,后台保存会将我的文本推送到服务器,而无需触摸我的焦点和编辑位置。
我尝试使用 EditController 和 SimpleFrom,这将重新渲染表单并从服务器获取记录器,并且失去焦点和编辑位置。 请问有什么例子或建议吗?
【问题讨论】:
我已经构建了一个名为 EditFormAutoSave 的插入式组件,您可以简单地将其添加到现有的 EditForm 以进行自动保存。它会在短暂的不活动等待时间间隔以及卸载编辑表单时保存所有更改的“脏”字段,以防止任何数据丢失。
用法
const YourResourceEdit = props => (
<Edit mutationMode="optimistic" {...props}>
<SimpleForm toolbar={<EditToolbar />}>
<EditFormAutoSave waitInterval={2000} />
<TextInput source="someFieldName" />
...
</SimpleForm>
</Edit>
)
EditFormAutoSave.js
import _ from 'lodash'
import {useEffect, useRef} from 'react'
import {useEditContext} from 'react-admin'
import {useFormState} from 'react-final-form'
const EditFormAutoSave = ({waitInterval = 1000}) => {
const {dirty, valid, values} = useFormState({subscription: {
dirty: true, valid: true, values: true,
}})
const {save, saving} = useEditContext()
const shouldSaveRef = useRef()
const saveDebouncedRef = useRef()
/*
* Determine whether 'save' should be called by any of the following effects. Use a
* 'ref' instead of a 'state' so that the unmount effect only fires on component
* unmount and therefor it musn't have any dependencies.
*/
useEffect(() => {
shouldSaveRef.current = dirty && valid && !saving
}, [dirty, saving, valid])
/*
* Debounce the 'save()' function and store it in a 'ref' for the same reason as above.
*/
useEffect(() => {
saveDebouncedRef.current = _.debounce(save, waitInterval)
}, [save, waitInterval])
/*
* Whenever the form data got dirty, schedule saving data
*/
useEffect(() => {
shouldSaveRef.current && saveDebouncedRef.current({...values}, /* redirectTo= */false)
}, [dirty, saving, valid, values])
/*
* On component unmount save any unsaved changes so that changed ("dirty") fields get
* persisted. Said differently this effects prevents data loss of unsaved changes.
*/
useEffect(() => () => {
shouldSaveRef.current && saveDebouncedRef.current.flush()
}, [])
return null
}
export default EditFormAutoSave
【讨论】: