Skip to content

Instantly share code, notes, and snippets.

@sanchitrk
Forked from jaredpalmer/Formik-Autosave.jsx
Created April 17, 2021 10:37
Show Gist options
  • Save sanchitrk/6f0ac1b3d1f6cded3ad607f057c2ddd5 to your computer and use it in GitHub Desktop.
Save sanchitrk/6f0ac1b3d1f6cded3ad607f057c2ddd5 to your computer and use it in GitHub Desktop.
Formik-Autosave
import React from 'react';
import PropTypes from 'prop-types'
import debounce from 'lodash.debounce' // or whatevs
import isEqual from 'lodash.isEqual'
class AutoSave extends React.Component {
static contextTypes = {
formik: PropTypes.object
}
state = {
isSaving: false,
}
componentWillReceiveProps(nextProps, nextContext) {
if (!isEqual(nextProps.values, this.props.values)) {
this.save()
}
}
save = debounce(() => {
this.setState({ isSaving: true, saveError: undefined })
this.props.onSave(this.props.values)
.then(
() => this.setState({ isSaving: false, lastSaved: new Date() }),
() => this.setState({ isSaving: false, saveError })
)
}), 300)
}
render() {
return this.props.render(this.state)
}
}
}
// Usage
import React from 'react';
import { Formik, Field, Form } from 'formik'
import distanceInWordsToNow from 'date-fns/distance_in_words_to_now'
const App = () =>
<div>
<h1>Signup form</h1>
<Formik
initialValues={{ firstName: '', lastName: ''}
onSubmit={values => {
setTimeout(() => {
alert(JSON.stringify(values, null,2))
}, 500)
}
render={() =>
<Form>
<Field name="firstName" />
<Field name="lastName" />
<button type="submit">Submit</button>
<AutoSave
onSave={values => CallMyApi(values) /* must return a promise 😎 */}\
debounce={1000}
render={({isSaving, lastSaved, saveError }) =>
<div>
{!!isSaving
? <Spinner/>
: !!saveError
? `Error: ${saveError}`
: lastSaved
? `Autosaved ${distanceInWordsToNow(lastSaved)} ago`
: 'Changes not saved'}
</div>
}
/>
</Form>
}
/>
</div>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment