Skip to content

Remove setState in ObjectField and ArrayField#480

Merged
n1k0 merged 4 commits intorjsf-team:masterfrom
knilink:remove-set-state
Feb 22, 2017
Merged

Remove setState in ObjectField and ArrayField#480
n1k0 merged 4 commits intorjsf-team:masterfrom
knilink:remove-set-state

Conversation

@knilink
Copy link
Copy Markdown
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
Copy Markdown
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
Copy Markdown
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};

constructor(props) {
super(props);
this.state = this.getStateFromProps(props);
}
Copy link
Copy Markdown
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.

constructor(props) {
super(props);
this.state = this.getStateFromProps(props);
}
Copy link
Copy Markdown
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
Copy Markdown
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
Copy Markdown
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
Copy Markdown
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
Copy Markdown
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.

toIdSchema,
shouldRender,
getDefaultRegistry,
setState
Copy link
Copy Markdown
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
Copy Markdown
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
Copy Markdown
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
Copy Markdown

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

@n1k0
Copy link
Copy Markdown
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
Copy Markdown
Collaborator

n1k0 commented Feb 22, 2017

👍

@Mitgenosse
Copy link
Copy Markdown

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
Copy Markdown
Contributor

MoOx commented Feb 22, 2017

Looks fantastic according to my test!

@stathismor
Copy link
Copy Markdown

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
Copy Markdown

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
Copy Markdown
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
Copy Markdown
Collaborator

n1k0 commented Feb 22, 2017

Released in v0.43.0.

@israelshirk
Copy link
Copy Markdown
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