Skip to content

Commit ec8816b

Browse files
committed
fix(children): Proper fix for checking children props for changes
See react-grid-layout#304
1 parent 6ed5187 commit ec8816b

File tree

2 files changed

+12
-5
lines changed

2 files changed

+12
-5
lines changed

lib/ReactGridLayout.jsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// @flow
22
import React, {PropTypes} from 'react';
33
import isEqual from 'lodash.isequal';
4-
import {autoBindHandlers, bottom, cloneLayoutItem, compact, getLayoutItem, moveElement,
4+
import {autoBindHandlers, bottom, childrenEqual, cloneLayoutItem, compact, getLayoutItem, moveElement,
55
synchronizeLayoutWithChildren, validateLayout} from './utils';
66
import GridItem from './GridItem';
77
const noop = function() {};
@@ -176,7 +176,7 @@ export default class ReactGridLayout extends React.Component {
176176
// If children change, also regenerate the layout. Use our state
177177
// as the base in case because it may be more up to date than
178178
// what is in props.
179-
else if (nextProps.children.length !== this.props.children.length) {
179+
else if (!childrenEqual(this.props.children, nextProps.children)) {
180180
newLayoutBase = this.state.layout;
181181
}
182182

lib/utils.js

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
// @flow
2+
import isEqual from 'lodash.isEqual';
3+
import React from 'react';
24
export type LayoutItemRequired = {w: number, h: number, x: number, y: number, i: string};
35
export type LayoutItem = LayoutItemRequired &
46
{minW?: number, minH?: number, maxW?: number, maxH?: number,
@@ -15,7 +17,6 @@ export type DragCallbackData = {
1517
export type DragEvent = {e: Event} & DragCallbackData;
1618
export type Size = {width: number, height: number};
1719
export type ResizeEvent = {e: Event, node: HTMLElement, size: Size};
18-
import type React from 'react';
1920

2021
const isProduction = process.env.NODE_ENV === 'production';
2122

@@ -53,10 +54,16 @@ export function cloneLayoutItem(layoutItem: LayoutItem): LayoutItem {
5354
};
5455
}
5556

57+
/**
58+
* Comparing React `children` is a bit difficult. This is a good way to compare them.
59+
* This will catch differences in keys, order, and length.
60+
*/
61+
export function childrenEqual(a: Array<React.Element<any>>, b: Array<React.Element<any>>): boolean {
62+
return isEqual(React.Children.map(a, c => c.key), React.Children.map(b, c => c.key));
63+
}
64+
5665
/**
5766
* Given two layoutitems, check if they collide.
58-
*
59-
* @return {Boolean} True if colliding.
6067
*/
6168
export function collides(l1: LayoutItem, l2: LayoutItem): boolean {
6269
if (l1 === l2) return false; // same element

0 commit comments

Comments
 (0)