jaredpalmer / formik

Build forms in React, without the tears 😭
https://formik.org
Apache License 2.0
34.01k stars 2.79k forks source link

Formik props leak? #1991

Open privateOmega opened 5 years ago

privateOmega commented 5 years ago

🐛 Bug report

Current Behavior

I have designed a page such that separate Formik forms are rendered based on a state variable eg. It should render the page with appropriate form when I change my selection in a dropdown select or something.

The problem is when I choose a different selection than before, Formik form is rendered twice. First time, the appropriate formik form is loaded with wrong values which causes other issues.

PS: I have added console statements to the form components to understand the values being passed onto it by formik's render method.

In the example that I have attached below

AFORM INITIAL VALUES 
Object {a: ""}
BFORM INITIAL VALUES 
Object {a: ""}
BFORM INITIAL VALUES 
Object {b: ""}

is the console output when I change my selection from a to b.

Reproducible example

https://codesandbox.io/embed/formik-example-9yebw?fontsize=14

Your environment

Software Version(s)
Formik 1.5.8
React 16.8.4
TypeScript
Browser Chrome 77.0.3865.120
npm/Yarn 1.15.2
Operating System Windows 10 Pro
privateOmega commented 5 years ago

@jaredpalmer PTAL

Joroze commented 5 years ago

I, too, noticed this issue.

When conditionally rendering two different Formik components under one container, the initialValues (or values) props leak into each other.

sanyatuning commented 5 years ago

workaround:

const renderSpecificForm = key => {
  switch (key) {
    case "a":
      return <FormA />;
    case "b":
      return <FormB />;
    default:
      return null;
  }
};

const FormA = () => (
  <Formik
    render={formikProps => <AForm {...formikProps} />}
    enableReinitialize={true}
    initialValues={{
      a: ""
    }}
  />
);
const FormB = () => (
  <Formik
    render={formikProps => <BForm {...formikProps} />}
    enableReinitialize={true}
    initialValues={{
      b: ""
    }}
  />
);
privateOmega commented 5 years ago

@sanyatuning Thanks, that works. Could you please post why it works? Am I missing some crucial React principle or idea?