- Notifications
You must be signed in to change notification settings - Fork 2.3k
Description
Prerequisites
- I have read the documentation.
Description
I believe the shouldRender function in utils.js is returning true in too many instances, particularly for nested ArrayFields or ObjectFields, because it's unnecessarily requiring function equality in props and state.
Steps to Reproduce
- In your clone of this repository, add this line to
shouldRender:console.log(comp.props, nextProps, !deeper(comp.props, nextProps) || !deeper(comp.state, nextState)); - Start the development server with
npm start - Go to
localhost:8080and click on the "Nested" tab - Start typing in the "Task list title" field
- Look in the console logs for something like
Object {name: "tasks".... This is whereshouldRenderwas called for the "tasks"ArrayField - Observe that the objects logged on that line are structurally equivalent, but that
shouldRenderis still returningtrue. I believe that this is happening only because theonChangefunctions in those objects are referentially non-equal.
Expected behavior
I would expect that shouldRender for the "tasks" ArrayField would return false and that the component does not re-render, because none of the data that affects how the component renders has changed. Re-rendering all ArrayFields or ObjectFields when none of the data in that component has changed, particularly in large forms, is a performance drain.
Actual behavior
ArrayField re-renders when making a change to another part of the form.
Version
0.34.1
Proposed Solution
I think that a function like the one below should be added to utils.js and called on comp.props and nextProps before they're passed to deeper
function _removeFunctionsFromObj(obj) { var newObj = {}; for (var key in obj) { if (typeof obj[key] !== 'function') { newObj[key] = obj[key]; } } return newObj; } I'd be happy to submit a PR, but I thought it might be better to start a discussion first in case there's another way to solve this problem.