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

Remove setState in ObjectField and ArrayField #480

Merged
merged 4 commits into from
Feb 22, 2017

Conversation

knilink
Copy link
Contributor

@knilink knilink commented Feb 21, 2017

Reasons for making this change

The preserving state in "ObjectField" and "ArrayField" was unnecessary because the root Form component had done the job(Form.js line 152). It may be the root cause of #339. (Haven't test it in IE but it did fix my losing characters issue).

Performance test has been updated due to componentWillReceiveProps in "ObjectField" and "ArrayField" are no longer necessary and have been removed.

Checklist

  • I'm updating documentation
    • I've checked the rendering of the Markdown text I've added
    • If I'm adding a new section, I've updated the Table of Content
  • I'm adding or updating code
    • I've added and/or updated tests
    • I've updated docs if needed
  • I'm adding a new feature
    • I've updated the playground with an example use of the feature

Copy link
Collaborator

@n1k0 n1k0 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, I'm sold. I'm pretty much amazed by this patch as it highlights how much unnecessary bloat was involved previously. I've tested the playground with your changes and couldn't spot any noticeable major behavioral change apart from a slight increase in performance and reactivity, which is awesome.

A few nits here and there and we're probably good to go.

Thanks a lot for your work 👍

{},
this.props.formData,
{[name]: value}
);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can do:

const newFormData = {...this.props.formData, [name]: value};

@@ -161,19 +161,6 @@ class ArrayField extends Component {

constructor(props) {
super(props);
this.state = this.getStateFromProps(props);
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The constructor is now unnecessary. Also that means we don't have local state anymore, which means we should use a functional stateless component instead of a component class. Which is so nice.

@@ -40,25 +21,6 @@ class ObjectField extends Component {

constructor(props) {
super(props);
this.state = this.getStateFromProps(props);
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same remark as with ArrayField, this should become a stateless component.

});
this.props.onChange([
...formData,
getDefaultFormState(itemSchema, undefined, definitions)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It may be worth renaming utils.getDefaultFormState which now sounds a little confusing. How about something like initDefaults?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure whether it is appropriate to do it at the moment because getDefaultFormState is used by the root Form component as well.

items: this.state.items.filter((_, i) => i !== index)
}, {validate: true}); // refs #195
this.props.onChange(
this.props.formData.filter((_, i)=> i !== index),
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: missing space before =>.

const {items} = this.state;
this.asyncSetState({
items: items.map((item, i) => {
const items = this.props.formData;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: this can alternatively be written as const {formData: items} = this.props;, which I personally like a lot. But here we could probably just use formData as it makes sense that they're a list of items in an ArrayField.

@@ -12,8 +12,7 @@ import {
retrieveSchema,
toIdSchema,
shouldRender,
getDefaultRegistry,
setState
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should check that this is still needed elsewhere. If not, we should remove that helper function, which is now obsolete.

// We *need* to replace state entirely here has we have received formData
// holding different keys (so with some removed).
this.state = state;
this.forceUpdate();
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm so happy seeing this going away 👍

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Me too :)

@Mitgenosse
Copy link

Nice work, I hope this fixes #399 .
Can you tell me when this will be merged and published?

@n1k0
Copy link
Collaborator

n1k0 commented Feb 21, 2017

@Gurkenschreck Once review comments are addressed.

Nice work, I hope this fixes #399 .

Maybe you could clone this branch and test it locally to see if it fixes/improves #339 (which is the issue you actually want to mention here I think)? That would give us useful feedback. Thanks!

@n1k0 n1k0 merged commit 4b6fe72 into rjsf-team:master Feb 22, 2017
@n1k0
Copy link
Collaborator

n1k0 commented Feb 22, 2017

👍

@Mitgenosse
Copy link

Mitgenosse commented Feb 22, 2017

Yes I can do that.
EDIT: It actually works locally on my IE11 Virtual Machine. Gonna try out IE9

@MoOx
Copy link
Contributor

MoOx commented Feb 22, 2017

Looks fantastic according to my test!

@stathismor
Copy link

If/when I get around adding support for anyOf as part of #417, I think I will need to bring the state back, but probably only using it for ArrayField's internal own stuff, and not for getting the formData as the code before this PR does.

@Mitgenosse
Copy link

Is anywhere stated what browsers are supported? The branch gh-pages cannot be seen in IE9.

Console output of https://mozilla-services.github.io/react-jsonschema-form/ in IE9

SCRIPT438: Object doesn't support property or method 'bind' 
bundle.js, line 1 character 226

I would raise an issue if IE9 should be supported.

@n1k0
Copy link
Collaborator

n1k0 commented Feb 22, 2017

We're not planning on supporting IE9. It looks like it could be achieved by including the right polyfills though, but I'd like to let developers (lib users) taking care of this.

But you're right we should document what our current target browser versions are.

n1k0 added a commit that referenced this pull request Feb 22, 2017
Highlights
---

- Improved performance and reactivity.
- More consistent validation behavior and UX for array field items.

Backward incompatible changes
---

- `ObjectField` and `ArrayField` are now stateless components, their
  local state handling has been dropped entirely, resulting in large
  performance improvements.
- The `defaultFieldValue` helper from the `utils` module has been
  removed, as it wasn't used anymore.

New features
---

* Fix #411:  Enable required field on radio options. (#469)
* Spread `formContext` to `ArrayTemplateField`, `files` and `multiselect`
  arrays (#456)
* From #471: Non-nullable array item fields are now marked as required in
  the UI.

Bugfixes
---

* Don't pass consumed `SchemaField` class names to child component (#439)
* Turn `ObjectField` and `ArrayField` into stateless components (#480)
* Fix #471: Drop default value initialization at the widget level. (#476)

Kudos
---

Special thanks to @crumblix and @knilink for their help on this release.
You guys rock!
@n1k0
Copy link
Collaborator

n1k0 commented Feb 22, 2017

Released in v0.43.0.

@combatpoodle
Copy link
Contributor

<3

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

Successfully merging this pull request may close these issues.

6 participants