Skip to content
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

Protect against children that may be null, this happens with conditio… #1296

Closed
wants to merge 6 commits into from

Conversation

jeffras
Copy link

@jeffras jeffras commented Sep 21, 2020

…nal rendering https://reactjs.org/docs/conditional-rendering.html#inline-if-with-logical--operator

Thanks for submitting a pull request to RGL!

Please reference an open issue. If one has not been created, please create one along with a failing
example or test case.

Please do not commit built files (/dist) to pull requests. They are built only at release.

@jeffras
Copy link
Author

jeffras commented Sep 21, 2020

Added issue 1297 for this PR

lib/utils.js Outdated Show resolved Hide resolved
@STRML
Copy link
Collaborator

STRML commented Oct 5, 2020

I haven't seen this come up before, do you have an example of where this is causing problems?

@jeffras
Copy link
Author

jeffras commented Oct 5, 2020

Here is the code that reproduces the issue. I believe using the inline condition returns a null child on the false case

import { WidthProvider, Responsive } from "react-grid-layout";

const ResponsiveReactGridLayout = WidthProvider(Responsive);
const originalLayouts = getFromLS("layouts") || {};

/**
 * This layout demonstrates how to sync multiple responsive layouts to localstorage.
 */
export default class ResponsiveLocalStorageLayout extends React.PureComponent {
  constructor(props) {
    super(props);

    this.state = {
      layouts: JSON.parse(JSON.stringify(originalLayouts))
    };
  }

  static get defaultProps() {
    return {
      className: "layout",
      cols: { lg: 12, md: 10, sm: 6, xs: 4, xxs: 2 },
      rowHeight: 30
    };
  }

  resetLayout() {
    this.setState({ layouts: {} });
  }

  onLayoutChange(layout, layouts) {
    saveToLS("layouts", layouts);
    this.setState({ layouts });
  }

  render() {
    const test = false; //NOTE: true works fine, but false seems to return a null child which crashes

    return (
      <div>
        <button onClick={() => this.resetLayout()}>Reset Layout</button>
        <ResponsiveReactGridLayout
          className="layout"
          cols={{ lg: 12, md: 10, sm: 6, xs: 4, xxs: 2 }}
          rowHeight={30}
          layouts={this.state.layouts}
          onLayoutChange={(layout, layouts) =>
            this.onLayoutChange(layout, layouts)
          }
        >
        {test &&
          <div key="1" data-grid={{ w: 2, h: 3, x: 0, y: 0, minW: 2, minH: 3 }}>
            <span className="text">1</span>
          </div>
          }
          <div key="2" data-grid={{ w: 2, h: 3, x: 2, y: 0, minW: 2, minH: 3 }}>
            <span className="text">2</span>
          </div>
          <div key="3" data-grid={{ w: 2, h: 3, x: 4, y: 0, minW: 2, minH: 3 }}>
            <span className="text">3</span>
          </div>
          <div key="4" data-grid={{ w: 2, h: 3, x: 6, y: 0, minW: 2, minH: 3 }}>
            <span className="text">4</span>
          </div>
          <div key="5" data-grid={{ w: 2, h: 3, x: 8, y: 0, minW: 2, minH: 3 }}>
            <span className="text">5</span>
          </div>
        </ResponsiveReactGridLayout>
      </div>
    );
  }
}

function getFromLS(key) {
  let ls = {};
  if (global.localStorage) {
    try {
      ls = JSON.parse(global.localStorage.getItem("rgl-8")) || {};
    } catch (e) {
      /*Ignore*/
    }
  }
  return ls[key];
}

function saveToLS(key, value) {
  if (global.localStorage) {
    global.localStorage.setItem(
      "rgl-8",
      JSON.stringify({
        [key]: value
      })
    );
  }
}```

@jeffras
Copy link
Author

jeffras commented Oct 5, 2020

And the error
image

lib/utils.js Outdated Show resolved Hide resolved
lib/utils.js Outdated Show resolved Hide resolved
lib/utils.js Outdated Show resolved Hide resolved
@github-actions
Copy link

github-actions bot commented Nov 5, 2020

This PR is stale because it has been open 30 days with no activity. Remove stale label or comment or this PR will be closed in 7 days

@github-actions github-actions bot added the stale The label to apply when a pull request or an issue is stale label Nov 5, 2020
@chenzhutian
Copy link

Is this pr merged?

@PierrickLozach
Copy link

Will this be merged? I am also facing this issue with conditional rendering

STRML added a commit that referenced this pull request Aug 26, 2021
Squashed commit of the following:

commit 5dfce15
Author: Jeff Rasmussen <[email protected]>
Date:   Mon Oct 5 14:51:58 2020 -0600

    Check for null or undefined

commit 79cf5bd
Author: Jeff Rasmussen <[email protected]>
Date:   Mon Oct 5 14:51:27 2020 -0600

    Undo vs code "help" regarding formatting style

commit b20a36c
Author: Jeff Rasmussen <[email protected]>
Date:   Mon Oct 5 14:20:44 2020 -0600

    Fix missed !

commit 36fede3
Author: Jeff Rasmussen <[email protected]>
Date:   Mon Oct 5 14:14:14 2020 -0600

    change check to validate against null instead of coercion to bool

commit c0e3a28
Author: Jeff Rasmussen <[email protected]>
Date:   Mon Oct 5 14:12:18 2020 -0600

    change check to validate against null instead of coercion to bool

commit 91a4650
Author: Jeff Rasmussen <[email protected]>
Date:   Mon Sep 21 12:57:44 2020 -0600

    Protect against children that may be null, this happens with conditional rendering https://reactjs.org/docs/conditional-rendering.html#inline-if-with-logical--operator
@STRML
Copy link
Collaborator

STRML commented Aug 26, 2021

Merged in 2591bf7

@STRML STRML closed this Aug 26, 2021
@PierrickLozach
Copy link

PierrickLozach commented Aug 27, 2021

Will you add this into a new release? I just pulled via yarn again (yarn add react-grid-layout) and I still get this from lib/utils.js:

  React.Children.map(a, c => c.key),
  React.Children.map(b, c => c.key)

instead of

  React.Children.map(a, c => c?.key),
  React.Children.map(b, c => c?.key)

@STRML
Copy link
Collaborator

STRML commented Aug 27, 2021

This is in 1.3.0.

@PierrickLozach
Copy link

Thanks! Issue is fixed now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
stale The label to apply when a pull request or an issue is stale
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants