-
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
Centralized handling shouldComponentUpdate into SchemaField #490
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.
Thanks again for your work :)
A few questions with the patch.
src/components/fields/SchemaField.js
Outdated
// idSchema and errorSchema will be equal | ||
delete _props.idSchema; | ||
delete _nextProps.idSchema; | ||
return !deepEquals(_props, _nextProps); |
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 confused with this code:
- the implementation doesn't reflect what the comment says; we're not dropping
errorSchema
; - the comment suggests we should only compare changes for
schema
andformData
, which is not what we're doing; - I suspect we should take care of
uiSchema
changes as well.
I'm trying to summarize the points above in a sample implementation below:
shouldComponentUpdate(nextProps) {
return !deepEquals(this.props.formData, nextProps.formData) ||
!deepEquals(this.props.schema, nextProps.schema) ||
!deepEquals(this.props.uiSchema, nextProps.uiSchema);
}
We may obviously want to ensure we're not missing other necessary checks, but I'm finding this way much more explicit.
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 comment suggests that "schema" and "formData" didn't change => "idSchema" and "errorSchema" didn't change. So, comparing "schema" and "formData" is enough to tell wheter "idSchema" and "errorSchema" have change or not.
But, not comparing errorSchema will fail some test. I haven't figure out the reason yet. And, the performance with comparing errorSchema looks acceptable.
I will update the comment.
src/components/fields/SchemaField.js
Outdated
if (Object.keys(schema).length === 0) { | ||
// See #312: Ensure compatibility with old versions of React. | ||
return <div/>; | ||
class SchemaField extends Component { |
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's really sad there's no way to have the equivalent of shouldComponentUpdate
for stateless components. I could totally see a decorator of some sort.
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 think React still need an instance to preserve props in order to have both "this.props" and "nextProps" to compare. recompose is one library I know to do such a thing. It will turn functions into classes.
test/performance_test.js
Outdated
|
||
sinon.assert.notCalled(comp.render); | ||
}); | ||
}); |
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.
Why has this test been removed?
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 "shouldComponnetUpdate" of "ObjectField" and "ArrayField" were guaranteed by "SchemaField". So, I thought those two function were no longer necessary and the related tests were removed.
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.
Pretty good! Thanks for this. A few formatting nits and we're good to go.
src/components/fields/SchemaField.js
Outdated
); | ||
} | ||
|
||
render(){ |
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: space before opening bracket
test/performance_test.js
Outdated
sandbox.stub(fieldComp, "render").returns(<div/>); | ||
fields[fieldComp.props.idSchema.$id] = fieldComp; | ||
return fields; | ||
}); |
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: let's apply a consistent coding style:
const fields = scryRenderedComponentsWithType(comp, SchemaField)
.reduce((fields, fieldComp) => {
sandbox.stub(fieldComp, "render").returns(<div/>);
fields[fieldComp.props.idSchema.$id] = fieldComp;
return fields;
});
Thank you 👍 |
New features * Add support for rows attribute of textarea widget. (#450) * #434 - Render empty array item fields when minItems is specified (#484) * Add a "has-danger" class to the form error list (#502) * Show description for boolean fields (#498) * Fix #488: Add a custom Form ErrorList prop. Bugfixes * Fix impossibility to use stateful ArrayFieldTeplate comp. (#519) * Centralized shouldComponentUpdate handling in SchemaField (#490)
Released in v0.44.0. |
Reasons for making this change
When one property is updated, the rest of the properties will be unnecessarily rendered.
This will cause a significant performance issue in a large object schema such as the demo of 'Large' in the playground.
Checklist