nikitaeverywhere / react-xmasonry

Simple, minimalistic and featured native masonry layout for React JS.
https://zitros.github.io/react-xmasonry
MIT License
91 stars 12 forks source link

Cannot read property 'displayName' of undefined #5

Closed aogaili closed 6 years ago

aogaili commented 6 years ago

Hello @ZitRos , I'm getting an error when mixing an XBlock to a map of XBlocks.

Here is simple code to reproduce the issue:

render() {
    const data = [1, 2, 3, 4, 5];
    return (
      <XMasonry>
        <XBlock key={0}>
          <div className="card">
            <h1>Card #{0}</h1>
            <p>Any text!</p>
          </div>
        </XBlock>
        {data.map(number =>
          <XBlock key={number}>
            <div className="card">
              <h1>Card #{number}</h1>
              <p>Any text!</p>
            </div>
          </XBlock>
        )}
      </XMasonry>
    );
  }
}

This will produce the following error in the console:

 Uncaught TypeError: Cannot read property 'displayName' of undefined
    at getDisplayName (modules.js?hash=d3a0317…:3230)
    at Object.getCurrentStackAddendum (modules.js?hash=d3a0317…:3340)
    at validateExplicitKey (modules.js?hash=d3a0317…:2918)
    at validateChildKeys (modules.js?hash=d3a0317…:2938)
    at Object.createElement (modules.js?hash=d3a0317…:3026)
    at XMasonry.render (XMasonry.jsx:385)
    at modules.js?hash=d3a0317…:18044
    at measureLifeCyclePerf (modules.js?hash=d3a0317…:17323)
    at ReactCompositeComponentWrapper._renderValidatedComponentWithoutOwnerOrContext (modules.js?hash=d3a0317…:18043)
    at ReactCompositeComponentWrapper._renderValidatedComponent (modules.js?hash=d3a0317…:18070)  

Any idea what might be causing this?

aogaili commented 6 years ago

For now I'm just pushing the addition block to the map and it's rendering correctly. But I'm still not sure why the above code is not working correctly.

getBlocks() {
    const data = [1, 2, 3, 4, 5];
    const blocks = data.map(number =>
      <XBlock key={number}>
        <div className="card">
          <h1>Card #{number}</h1>
          <p>Any text!</p>
        </div>
      </XBlock>
    );

    blocks.unshift(
      <XBlock key={0}>
        <div className="card">
          <h1>Card #{0}</h1>
          <p>Any text!</p>
        </div>
      </XBlock>
    );
    return blocks;
  }

  render() {
    const blocks = this.getBlocks();
    return (
      <XMasonry>
        {blocks}
      </XMasonry>
    );
  }
nikitaeverywhere commented 6 years ago

Hm. In my project, I did the same as you did and it worked perfectly. Currently I cannot test this on my laptop, could you please make an example of this on CodePen/whatever? Thanks!

aogaili commented 6 years ago

Alright I'll try to replicate this issue on fresh Meteor project. If the issue persists, then I'll try to reproduce it in CodePen and share it with you.

aogaili commented 6 years ago

Hello @ZitRos, I got different errors when I tried reproducing the issue on Codepen, you can see me attempt here.

However I was able to reproduce this issue and issue #3 with minimal meteor setup which you can find here.

There are workarounds for both issues, so they're not urgent, I can attempt to dig deeper once I get more time.

nikitaeverywhere commented 6 years ago

minimal meteor setup which you can find here.

Thank you very much on making this example!

Regarding to the originally described issue, I've found a problem and I am currently solving it. The problem was in this.props.children, which XMasonry works with as a flat array while it is an opaque data structure.

nikitaeverywhere commented 6 years ago

Version 2.4.0 just got published. Please, let me know if this fixes the issue (I know it is, but in any case... 😄).

aogaili commented 6 years ago

Great work @ZitRos, works perfectly now!