简体   繁体   中英

Updating state in React.js component leaves blank space under my page

I have a React.js component that renders a list of elements on page load, but this list can be updated with a filter that will remove certain elements from the list and save the modified list in the component's state. I managed to make this functionnality work, so the state is updated correctly.

While the elements get re-rendred correcly, less space is used when less elements are rendred. When this happens, the page's height doesn't shrink to adapt to the new size occupied by the page and leaves empty content under my footer, which is the last element of my page.

Edit :

I looked a bit more into this and I think React.js may not be the cause of my problem. I call a function that uses imagesLoaded and Wookmark jQuery plugins after each update of the component's state and it looks like calling this function after each state change does not work well. Is there something I should change in the called function or I should call the function at another point in time?

var ActivityListClass = React.createClass({
loggedInUser: {},
componentDidUpdate: function() {
    activityListImageResponsiveness(); // This is the function
},
componentDidMount: function() {
    var theActivityList = this;
    var activitiesGetListener = postal.subscribe({
        channel: "activities",
        topic: "list",
        callback: function(data, envelope) {
            var dataClone = $.extend(true, {}, data);
            dataClone.activities.shift();
            theActivityList.setState({data: dataClone.activities});
            theActivityList.loggedInUser = dataClone.loggedInUser;
        }
    });
},
getInitialState: function() {
    return {data: []};
},
render: function() {
    var i = 0;
    var activityNodes = this.state.data.map(function(activity) {
        var currentId = i;
        i++;
        return (
            <ActivityClass key={currentId} data={activity} />
        );
    });
    return (
        <section id="listArticles">
            {activityNodes}
        </section>
    );
}
});

And the function called is defined like this :

function activityListImageResponsiveness() {
    $('#listArticles').imagesLoaded(function() {
        // Get a reference to your grid items.
        var $handler = $('#listArticles article');

        $handler.on("webkitTransitionEnd otransitionend oTransitionEnd msTransitionEnd transitionend", function(event) {
            if(event.originalEvent.propertyName == 'top'){
                $('#listArticles').trigger("refreshWookmark");
            }
        });

        // Prepare layout options.
        var options = {
            align: 'left',
            autoResize: true, // This will auto-update the layout when the browser window is resized.
            container: $('#listArticles'), // Optional, used for some extra CSS styling
            direction: 'left',
            fillEmptySpace: true, // Optional, fill the bottom of each column with widths of flexible height
            flexibleWidth: '16.635%',
            itemWidth: $handler.width(), // Optional, the width of a grid item
            offset: 42, // Optional, the distance between grid items
            verticalOffset: 15
        };

        var $window = $(window);
        $window.resize(function() {
            var windowWidth = $window.width(),
            newOptions = {
                flexibleWidth: '16.635%',
                itemWidth: 208
                };

            // NOTE: These values are the same as the "media queries" of the CSS file.
            if(windowWidth >= 1263){
                newOptions.flexibleWidth = '16.635%';
                newOptions.itemWidth = 208;
            } else if (windowWidth >= 1132){
                newOptions.flexibleWidth = '21.05263157894737%';
                newOptions.itemWidth = 236;
            }else if(windowWidth >= 1014){
                newOptions.flexibleWidth = '20.71713147410359%';
                newOptions.itemWidth = 208;
            }else if(windowWidth >= 852){
                newOptions.flexibleWidth = '27.99525504151839%';
                newOptions.itemWidth = 236;
            }else if(windowWidth >= 764){
                newOptions.flexibleWidth = '27.51322751322751%';
                newOptions.itemWidth = 208;
            }else if(windowWidth >= 626){
                newOptions.flexibleWidth = '42.58064516129032%';
                newOptions.itemWidth = 264;
            }else if(windowWidth >= 515){
                newOptions.flexibleWidth = '40.7843137254902%';
                newOptions.itemWidth = 208;
            }else{
                newOptions.flexibleWidth = '83.80952380952381%';
                newOptions.itemWidth = 264;
            }

        $handler.wookmark(newOptions);
    });
    // Call the layout function.
    $handler.wookmark(options);
    });
}

I found that Wookmark leaves behind invisible divs in the listArticles section that contains my rendered elements, which explains why I had a weird blank space in the bottom of my page. I tried removing all these divs before each render with $("#listArticles .wookmark-placeholder").remove(); It looks like it's working, but renders of the component are a bit slower.

To do this, I added the componentWillUpdate function to my React component:

componentWillUpdate: function() {
    $("#listArticles .wookmark-placeholder").remove();
},

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM