Skip to content

Instantly share code, notes, and snippets.

@jaredpalmer
Last active December 29, 2022 01:22
Show Gist options
  • Save jaredpalmer/56e10cabe839747b84b81410839829be to your computer and use it in GitHub Desktop.
Save jaredpalmer/56e10cabe839747b84b81410839829be to your computer and use it in GitHub Desktop.

Revisions

  1. jaredpalmer revised this gist Oct 4, 2017. 1 changed file with 6 additions and 11 deletions.
    17 changes: 6 additions & 11 deletions Formik-Autosave.jsx
    Original file line number Diff line number Diff line change
    @@ -3,7 +3,6 @@ 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
    @@ -20,16 +19,12 @@ class AutoSave extends React.Component {
    }

    save = debounce(() => {
    // do whatever you want to save stuff
    // this.props.handleSubmit({ preventDefault: () => {} })
    // or
    // imagine handleCommit has to return a promise?
    this.setState({ isSaving: true })
    this.props.onSave(this.props.values)
    .then(
    () => this.setState({ isSaving: false, lastSaved: new Date() }),
    () => this.setState({ isSaving: false, saveError })
    )
    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)
    }

  2. jaredpalmer renamed this gist Oct 4, 2017. 1 changed file with 0 additions and 0 deletions.
    File renamed without changes.
  3. jaredpalmer created this gist Oct 4, 2017.
    81 changes: 81 additions & 0 deletions withAutoSave.jsx
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,81 @@
    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(() => {
    // do whatever you want to save stuff
    // this.props.handleSubmit({ preventDefault: () => {} })
    // or
    // imagine handleCommit has to return a promise?
    this.setState({ isSaving: true })
    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>