Lazy uploads of images, videos, and frames to ReactJS.

I have a component-component render on page load. The content includes a lot of multimedia materials, which I want to lazy to download only when the content is on the screen, and then unloads it when it is missing. More content loads as the user scrolls.

I use a combination of methods to handle lazy downloadable frames, videos, and images, and it works great outside of the content passed through React. Mostly custom jQuery and the "Lazy Load Anything " library .

My main problem is that I cannot get my lazy boot function to run content just placed in dom. It works when the user resizes / scrolls (I have events for this that fire accordingly). How to make it run when content is available?

I tried to launch it from componentDidMount component, but this does not seem to work as the content has not yet been placed in the DOM.

I suppose I can just check the contents every n seconds, but I would like to avoid this for performance reasons.

Here is my simplified code:

var EntriesList = React.createClass({
    render: function() {
        var entries = this.props.items.map(function(entry) {
            return (
                <div className="entry list-group-item" key={entry.id}>
                    // lazy items video, image, iframe...
                    <img src="1px.gif" className="lazy" datasource="/path/to/original" />
                    <video poster="1px.gif" data-poster-orig="/path/to/original" preload="none">{entry.sources}</video>
                </div>
            );
        });

        return(<div>{entries}</div>);
    }
});


var App = React.createClass({
    componentDidMount: function() {
        $.get('/path/to/json', function(data) {
            this.setState({entryItems: data.entries});
        }.bind(this));

        // What do I put here to trigger lazy load? for the rendered content?
        myLazyLoad(); // does not work on the new content.

    },
    getInitialState: function() {
        return ({
            entryItems: []
        });
    },
    render: function() {
        return (<div><EntriesList items={this.state.entryItems} /></div>);
    }
});

React.render(<App />, document.getElementById('entries'));
+3
source share
4 answers

jquery, DOM - , React. lazy load EntriesList, .

- :

https://github.com/loktar00/react-lazy-load

, .

var EntriesList = React.createClass({
    render: function() {
        var entries = this.props.items.map(function(entry) {
            return (
                <div className="entry list-group-item" key={entry.id}>

                    // lazy items video, image, iframe...
                    <LazyLoad>
                       <img src="1px.gif" datasource="/path/to/original" />
                       <video poster="1px.gif" data-poster-orig="/path/to/original" preload="none">{entry.sources}</video>
                    </LazyLoad>

                </div>
            );
        });

        return(<div>{entries}</div>);
    }
});
+2

div (div, App:

var App = React.createClass({
    componentDidMount: function() {
        $.get('/path/to/json', function(data) {
            this.setState({entryItems: data.entries});
        }.bind(this));
    },

    myLazyLoad: function(e) {
        // here do actions that you need: load new content, do ajax request, ...
        // example: check you scrolling and load new content from page 1, 2, 3 ... N
        var self = this;
        $.get('path/to/json/?page=N', function(data) {
            self.setState({entryItems: data.entries});
        });
    },

    getInitialState: function() {
        return ({
            entryItems: []
        });
    },
    render: function() {
        return (<div onScroll={this.myLazyLoad}><EntriesList items={this.state.entryItems} /></div>);
    }
});
0

With the npm package react-lazy-load-image-component you just need to wrap the components you want to be lazy to load with <LazyLoadComponent>, and this will work without any other configuration.

import { LazyLoadComponent } from 'react-lazy-load-image-component';

var EntriesList = React.createClass({
    render: function() {
        var entries = this.props.items.map(function(entry) {
            return (
                <LazyLoadComponent>
                    <div className="entry list-group-item" key={entry.id}>
                        // lazy items video, image, iframe...
                        <img src="1px.gif" className="lazy" />
                        <video poster="1px.gif" data-poster-orig="/path/to/original" preload="none">{entry.sources}</video>
                    </div>
                </LazyLoadComponent>
            );
        });

        return(<div>{entries}</div>);
    }
});


var App = React.createClass({
    componentDidMount: function() {
        $.get('/path/to/json', function(data) {
            this.setState({entryItems: data.entries});
        }.bind(this));

    },
    getInitialState: function() {
        return ({
            entryItems: []
        });
    },
    render: function() {
        return (<div><EntriesList items={this.state.entryItems} /></div>);
    }
});

React.render(<App />, document.getElementById('entries'));

Disclaimer: I am the author of the package.

0
source

All Articles