paulcollett / react-masonry-css

React Masonry layout component powered by CSS, dependancy free
https://paulcollett.github.io/react-masonry-css/demo/
MIT License
950 stars 66 forks source link

my cards always rerender #51

Open Taha-Seddik opened 4 years ago

Taha-Seddik commented 4 years ago

After wrapping my cards with react-masonry-css the shouldComponentUpdate in my card component is ignored and my cards keeps rendering ! can someone help me how to solve this issue ?

 render() {
        // console.log("render CardsContainer")
        const {
            view,
            cells,
            memberAvatar,
            imageThumbnail,
            COLORS_CONFIG,
            zoomValue,
        } = this.props;

        return (
            <React.Fragment>
                <Masonry
                    breakpointCols={6}
                    className="my-masonry-grid"
                    columnClassName="my-masonry-grid_column">

                    {cells[0][0].map((item, itemIndex) => (
                        <CardComponent
                            zoomValue={zoomValue}
                            key={item.getEntity().getId()}
                            itemIndex={itemIndex}
                            item={item}
                            view={view}
                            imageThumbnailFilter={imageThumbnail}
                            memberAvatarFilter={memberAvatar}
                            colorConfig={
                                COLORS_CONFIG.OptionsBackgroundColorsByPallete[0]
                            }
                            colorConfigRGB={
                                COLORS_CONFIG.OptionsBackgroundColorsByPallete[1]
                            }
                        />
                    ))}

                </Masonry>

            </React.Fragment >

        );
    }
zliangs commented 4 years ago

I have the same issue. How to solve it? Thanks @paulcollett @NoobDay @dandv

Taha-Seddik commented 4 years ago

I figured out the cause of continuous mounting and unmounting

I was changing the number of columns of masonry layout and react was continuously constructing the layout with cards When a card moves from a column to another column it unmount and mount

for that i did put a constant number of columns and the problem was solved

Taha-Seddik commented 4 years ago

I checked the code of library i found that some sort of transformation to the component childrens caused the rerender below some code from this library source code


 itemsInColumns() {
        const currentColumnCount = this.state.columnCount;
        const itemsInColumns = new Array(currentColumnCount);

        // Force children to be handled as an array
        const items = [].concat(this.props.children|| []);

        for (let i = 0; i < items.length; i++) {
            const columnIndex = i % currentColumnCount;

            if (!itemsInColumns[columnIndex]) {
                itemsInColumns[columnIndex] = [];
            }

            itemsInColumns[columnIndex].push(items[i]);
        }

        return itemsInColumns;
    }

and in the render he is displaying the array

const childrenInColumns = this.itemsInColumns();
return childrenInColumns.map((items, i) => {
          return <div
            key={i}
          >
            {items}
          </div>; 

without this transformation everything works normally

Taha-Seddik commented 4 years ago

hope u got an idea about why i got this issue and how i solved it also what causes the render hell

zliangs commented 4 years ago

thank you so much @NoobDay

paulcollett commented 4 years ago

to confirm, this re-render only occurs on a column count change?

If so, that's an expected trade-off due to this technique which requires wrapping each column in an extra <div>. Unfortunately React doesn't optimise for "moving" a Component or it's dom elements between a shared ancestor element - It simply un-mounts and re-mounts.

We've looked into various workarounds, like <Portals> without success.

If this affects your Component's state, we suggest lifting the state above Masonry.

Taha-Seddik commented 4 years ago

yep that's it