jaredpalmer / formik-effect

Declarative component for managing side-effects in Formik forms. 580 bytes
https://npm.im/formik-effect
MIT License
166 stars 13 forks source link

Consider deprecating this in favor of @reach/component-component #5

Open cloud-walker opened 5 years ago

cloud-walker commented 5 years ago

First of all, thanks again for the amazing work on formik, I've recently upgraded it from 0.* to 1.3 without breaking changes 😲!

I think this package brings not so much value considering more generic alternatives, like: https://ui.reach.tech/component-component

I propose to deprecate this redirecting the new users to the alternatives!

Comparison

// withFormikEffect.js
import React from 'react'
import ReactDOM from 'react-dom'
import {Formik, Form, Field} from 'formik'
import {Effect} from 'formik-effect'

const App = () => (
  <div>
    <h1>Formik with formik-effect</h1>
    <Formik onSubmit={console.log} initialValues={{nickname: '', password: ''}}>
      {formik => (
        <Form>
          <Effect
            onChange={(currentFormik, nextFormik) =>
              console.log(currentFormik, nextFormik)
            }
          />

          <Field name="nickname" />
          <Field name="password" />
          <input type="submit" />
        </Form>
      )}
    </Formik>
  </div>
)

const rootElement = document.getElementById('root')
ReactDOM.render(<App />, rootElement)

vs

// withComponentComponent.js
import React from 'react'
import ReactDOM from 'react-dom'
import {Formik, Form, Field} from 'formik'
import Component from '@reach/component-component'

const App = () => (
  <div>
    <h1>Formik with formik-effect</h1>
    <Formik onSubmit={console.log} initialValues={{nickname: '', password: ''}}>
      {formik => (
        <Form>
          <Component
            formik={formik}
            didUpdate={({prevProps, props}) => {
              console.log(prevProps.formik, props.formik)
            }}
          />

          <Field name="nickname" />
          <Field name="password" />
          <input type="submit" />
        </Form>
      )}
    </Formik>
  </div>
)

const rootElement = document.getElementById('root')
ReactDOM.render(<App />, rootElement)

The difference is minimal and u can do it in other ways also (for example passing only the formikBag props you want to Component)

jedrichards commented 5 years ago

@cloud-walker The <Effect/> API explicitly lets you mutate the Formik state as it passes through the onChange handler. What's the technique for doing the same in component-component's didUpdate?

cloud-walker commented 5 years ago

Hi @jedrichards, I'm not sure of what your are talking about, can you provide an example?

jedrichards commented 5 years ago

@cloud-walker Hmm, maybe I'm misunderstanding. As I understand it one of the use cases for <Effect/> was to trigger changes in the form state when a field changes. That is, when one field change should trigger a change in another field ... so changing a startDate field should automatically update an endDate field to be some date to the future of startDate (for example).

How would you do that within didUpdate in your example above?

cloud-walker commented 5 years ago

@jedrichards you mean something like this: https://codesandbox.io/s/ww1lv6386k

jedrichards commented 5 years ago

@cloud-walker Yeah exactly. Got it now - thanks! 🙇

MikeSuiter commented 5 years ago

@cloud-walker I'm trying to use your suggestion in my app to submit whenever a select field changes value and it works with Formik 1.3.X but not with 1.4.X. Somewhere in the Formik validation code (my form has no validation) it is setting isCanceled: true which I'm assuming keeps the handleSubmit() from getting called. More details on what's going on here:

https://github.com/jaredpalmer/formik/issues/1209

Here is the sandbox showing what I'm doing and that handleSubmit() doesn't get called with 1.4.1. If you change the Formik version to 1.3.2 it works.

Edit Formik Effect vs Component^2

I posted here in case you might know what's going on. I really want to use Component Component in a few places in our app but this is a blocker.

cloud-walker commented 5 years ago

Hi, why you need to do formik.submitForm manually? I've played with your example and to me it works just fine: https://codesandbox.io/s/p70o0plr4q

MikeSuiter commented 5 years ago

Kind of an edge case to submit a form on a field change but in our real app we have a select field that when changed will make a REST call to filter the grid contents. I think it's a better experience to submit the form on change rather than making them select then hit a button. The sandbox is a dumb example but did show what was going on.

Jared pointed me in a right direction and for this I'm not using Component-Component. There are some places where we need to update a field based on a value from another field so I want to try C-C there. Here is my solution for submitting on a select field change.

https://github.com/jaredpalmer/formik/issues/1209#issuecomment-450027026