Layout is not respected when passed by props Continued
See original GitHub issueI’m bringing up #870 again because I can’t prevent the component from setting a new layout with the current implementation.
Desired behavior
If I pass a layout as props, that layout should be what appears on the screen.
Use Case
I wish to manage the layouts on my own. When onLayoutChange fires I will handle the change with my own logic (namely, some reducer in redux), and pass the updated layout to ReactGridLayout. In some cases, the layout should not change and revert to the “current layout.”
Current behavior
Because lodash.isEqual is used to compare the previous layout’s state and the current props layout, if I pass in the “current layout” it is ignored and a new layout is put in place as if I weren’t managing it
Relevant code:
In file ReactGridLayout.jsx these lines are preventing the desired behavior:
Proposed fix
Ideally, I would change !isEqual(nextProps.layout, prevState.propsLayout) to nextProps.layout !== prevState.propsLayout, and put the onus on the user to insure that shallow reference comparison will be enough to determine if the layout in props is actually a new layout or not. However, I can see this possibly breaking some components which recreate their layout on each render (which they probably shouldn’t be doing…).
I propose either the above change, or perhaps a flag prop on ReactGridLayout, such as managed, which would allow the user to opt-in to shallow reference comparison in the above code. For example:
if (
!isEqual(nextProps.layout, prevState.propsLayout) ||
nextProps.compactType !== prevState.compactType ||
(nextProps.managed && (nextProps.layout !== prevState.propsLayout))
) {
The managed prop should get a default value of false so that existing code will work as if it is not there.
If @STRML doesn’t see any major issues with this, I’ll make a PR implementing the change.
Issue Analytics
- State:
- Created 3 years ago
- Reactions:4
- Comments:10

Top Related StackOverflow Question
@STRML Thanks for your response. I put some code together demonstrating the issue on codebox. I hope that the comments explain what is going on well enough, but the point is that, when “L1” is the selected layout, the user should not be able to change the layout. The box can drag the boxes, but when the mouse is released it should go back to its original position. When “L2” is selected, the user can change the layout as she pleased, and and when she goes to “L1” then back to “L2”, that layout is remembered.
This behavior is precisely what occurs when
!isEqual(nextProps.layout, prevState.propsLayout)is changed tonextProps.layout !== prevState.propsLayout. I think it makes it even more clear when I consider a “case analysis matrix” comparing the use ofisEqualto!==…isEqualand===isEqualand!==!isEqualand!==!isEqualand===!==by using a spread operator when passing the layout as props.Basically, I don’t understand the reasoning behind using
_.isEqual. It seems to disable a use case, and reference comparison seems to be more “react-y”. If there is a good reason for using_.isEqual, then I’m certainly curious. Any thoughts?I think this is a sane idea. A flag could maintain compatibility in this major version, and in a future version a HOC could do the management for the usual use case.
This could also get us on the road to the plan in #346 which is to split the transformation of the
layout(compaction and conflict resolution) into interfaces that can be passed into the HOC as props or used as-needed, exported from the library. This increases the API surface area which increases the propensity for breaking changes, but it also allows new features to proceed unimpeded as plugins, outside of the RGL library. Such a design would be much, much cleaner and more flexible.Needless to say I’m not exceptionally proud of how RGL has “organically” developed from my original needs in ~2015. It works, but it’s not particularly good at anything outside its expected use case and can’t be meaningfully extended.