在 ReactJS 渲染的内容中延迟加载图像、视频和 iframe

IT技术 javascript jquery reactjs
2021-05-11 01:30:07

我在页面加载时有一个react组件渲染。内容包括许多富媒体,我只想在内容出现在屏幕上时才延迟加载,然后在内容不在时将其卸载。当用户滚动时加载更多内容。

我正在使用多种技术来处理延迟加载 iframe、视频和图像,并且它在通过 React 呈现的内容之外运行良好。主要是自定义 jQuery 和Lazy Load Anything库。

我的主要问题是我无法让我的延迟加载功能触发刚刚放入 dom 的内容。一旦用户调整大小/滚动(我有一个适当触发的事件),它就会工作。如何在内容可用时触发它?

我试过从 componentDidMount 触发它,但这似乎不起作用,因为内容尚未放入 DOM 中。

我想我可以每n检查一次内容,但出于性能原因我想避免这种情况。

这是我的简化代码:

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'));
4个回答

如果您尝试使用 jquery 插件,您可能会以与 React 呈现的 DOM 不同步的方式结束。同样在您的情况下,应该在EntriesList组件中调用延迟加载函数,而不是从其父级调用

您可以使用一个非常简单的组件作为 react-lazy-load:

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>);
    }
});

使用 npm 包react-lazy-load-image-component,你只需要包装你想要延迟加载的组件,<LazyLoadComponent>它就可以在没有任何其他配置的情况下工作。

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'));

免责声明:我是该软件包的作者。

尝试检查滚动事件到您的 div 父容器(您在 App 类上呈现的 div:

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>);
    }
});

延迟加载react

组件可以在其消费者不知道使用高阶函数的情况下延迟加载依赖项,或者消费者可以在其子代不知道的情况下延迟加载其子代,该组件使用带有函数和module集合的组件,或两者的某种组合。

https://webpack.js.org/guides/lazy-load-react/