Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Form switching results in merged formData #231

Closed
dpwrussell opened this issue Jun 8, 2016 · 12 comments
Closed

Form switching results in merged formData #231

dpwrussell opened this issue Jun 8, 2016 · 12 comments
Labels

Comments

@dpwrussell
Copy link

Prerequisites

Description

When switching between forms, displaying one form, then another, then back to the original, the submitted formData will be merged between the two forms.

Steps to Reproduce

I made a minimal example here: https://github.com/dpwrussell/react-jsonschema-form/tree/broken
Just clone that, npm install, npm start. There are two hyperlinks in the top-right corner to switch between the two forms.

  1. Goto 'Simple' form. Don't submit.
  2. Goto 'Large' form (this has defaults and will trigger the problem). Don't submit.
  3. Go back to 'Simple' form.
  4. Modify a value.
  5. Press submit and see the submitted formData in the console.

Expected behavior

formData would be exclusively of the current 'Simple' form.

Actual behavior

formData includes data from 'Large' form.

Version

master branch and released versions

@n1k0
Copy link
Collaborator

n1k0 commented Jun 8, 2016

I didn't test your patch (maybe a jsfiddle would be more convenient), but at first glance it seems to me that the Form should just use what's provided as a formData object, meaning it's the responsibility of the developer to not mutate it before it's passed as a prop to the component.

Reminds me the conversation in #181.

@dpwrussell
Copy link
Author

I have not mutated the formData that I pass in.

I render a form (specifying it's formData), I then render a different form (specifying it's formData also). I then rerender the original form (again specifying the unmutated original formData). If you then modify one of the fields and submit, the formData that is submitted has data in it from the other form. The only way this could be the case is if it is somehow being saved inside the Form component class.

In my example, I store formData per form, so there is no possibility that the intermediate form mutated the original/final form's formData.

@dpwrussell
Copy link
Author

I just pushed another commit, logging the explicitly passed in formData when rendering each form. It is unmutated.

Passed in form data
app.js:112 Object {firstName: "Chuck", lastName: "Norris", age: 75, bio: "Roundhouse kicking asses since 1940", password: "noneed"}
#Switch to Large
app.js:111 Passed in form data
app.js:112 Object {}
#Switch back to Simple
app.js:111 Passed in form data
app.js:112 Object {firstName: "Chuck", lastName: "Norris", age: 75, bio: "Roundhouse kicking asses since 1940", password: "noneed"}
#Modify then submit Simple
app.js:91 Object {status: "editing", formData: Object, edit: true, errors: Array[0], errorSchema: Object…}edit: trueerrorSchema: Objecterrors: Array[0]formData: Objectage: 75bio: "Roundhouse kicking asses since 1940"choice1: "option #0"choice2: "option #0"choice3: "option #0"choice4: "option #0"choice5: "option #0"choice6: "option #0"choice7: "option #0"choice8: "option #0"choice9: "option #0"choice10: "option #0"firstName: "Chucky"lastName: "Norris"password: "noneed"string: undefined__proto__: ObjectidSchema: Objectstatus: "editing"__proto__: Object

@dpwrussell
Copy link
Author

As a jsfiddle: https://jsfiddle.net/f2y3fq7L/5/

@n1k0
Copy link
Collaborator

n1k0 commented Jun 8, 2016

Thanks for the fiddle, it really helped. There's indeed an issue, seems like we're keeping a reference to defaults. Definitely a bug.

@n1k0 n1k0 added the bug label Jun 8, 2016
@dpwrussell
Copy link
Author

I guess it is probably caused by copying props to state. Sometime unavoidable, but perhaps not in this case? https://facebook.github.io/react/tips/props-in-getInitialState-as-anti-pattern.html

@mplis-jetsetter
Copy link
Contributor

Not sure if this is related, but I'm seeing similar behavior on the playground site.

To reproduce:

  1. To go the "Simple" tab
  2. Remove "age" from JSONSchema, UISchema, and formData
  3. Make some change to the form (e.g. start typing in "First name" field)

Then you'll see "age" pop back up in the formData.

@n1k0
Copy link
Collaborator

n1k0 commented Jun 9, 2016

I guess it is probably caused by copying props to state. Sometime unavoidable, but perhaps not in this case?

While most components are stateless, the Form, ObjectField and ArrayField are inherently stateful as you're basically building them up in memory locally to the component instance before propagating their state when it's ready. And as these are inherently bi-directional (because at some point you might want to populate fields with external data), you basically need to reflect these new incoming data into these component states (through props).

Using something like redux would basically move the problem elsewhere, adding more code and levels of indirection while we would still have to manage field state. Note: this might be an option eventually, but right now I'm reluctant at introducing more complexity to a somewhat already complex library (forms are complex anyway).

I'm working on fixing the bug atm anyway :)

@n1k0
Copy link
Collaborator

n1k0 commented Jun 9, 2016

Please provide feedback on #234.

@n1k0
Copy link
Collaborator

n1k0 commented Jun 9, 2016

Released in v0.33.2

@dpwrussell
Copy link
Author

I'm not familiar with the process for publishing to npm, but I noticed it hasn't updated on npm yet. Possibly there is just a delay involved?

@n1k0
Copy link
Collaborator

n1k0 commented Jun 9, 2016

Oops, forgot to run the publish command; should be published now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants