-
Notifications
You must be signed in to change notification settings - Fork 2.2k
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
Conversation
There was a problem hiding this 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 👍
src/components/fields/ObjectField.js
Outdated
{}, | ||
this.props.formData, | ||
{[name]: value} | ||
); |
There was a problem hiding this comment.
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};
src/components/fields/ArrayField.js
Outdated
@@ -161,19 +161,6 @@ class ArrayField extends Component { | |||
|
|||
constructor(props) { | |||
super(props); | |||
this.state = this.getStateFromProps(props); | |||
} |
There was a problem hiding this comment.
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.
src/components/fields/ObjectField.js
Outdated
@@ -40,25 +21,6 @@ class ObjectField extends Component { | |||
|
|||
constructor(props) { | |||
super(props); | |||
this.state = this.getStateFromProps(props); | |||
} |
There was a problem hiding this comment.
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) |
There was a problem hiding this comment.
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
?
There was a problem hiding this comment.
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.
src/components/fields/ArrayField.js
Outdated
items: this.state.items.filter((_, i) => i !== index) | ||
}, {validate: true}); // refs #195 | ||
this.props.onChange( | ||
this.props.formData.filter((_, i)=> i !== index), |
There was a problem hiding this comment.
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; |
There was a problem hiding this comment.
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 |
There was a problem hiding this comment.
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(); |
There was a problem hiding this comment.
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 👍
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Me too :)
Nice work, I hope this fixes #399 . |
👍 |
Yes I can do that. |
Looks fantastic according to my test! |
If/when I get around adding support for |
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
I would raise an issue if IE9 should be supported. |
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. |
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!
Released in v0.43.0. |
<3 |
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