Javascript 如何在内联样式属性(React)中延迟加载背景图像?

Javascript 如何在内联样式属性(React)中延迟加载背景图像?,javascript,reactjs,lazy-loading,Javascript,Reactjs,Lazy Loading,我目前正在开发我的第一个React应用程序,我面临着一些困难(对我来说) 我想懒加载背景图片 我还没有找到做这件事的好组件/实用程序。 有人有什么想法吗?这里有一个用于延迟加载图像的简单组件: class LazyBackground extends React.Component { state = { src: null }; componentDidMount() { const { src } = this.props; const imageLoader

我目前正在开发我的第一个React应用程序,我面临着一些困难(对我来说)


我想懒加载背景图片

我还没有找到做这件事的好组件/实用程序。
有人有什么想法吗?

这里有一个用于延迟加载图像的简单组件:

class LazyBackground extends React.Component {
  state = { src: null };

  componentDidMount() {
    const { src } = this.props;

    const imageLoader = new Image();
    imageLoader.src = src;

    imageLoader.onload = () => {
      this.setState({ src });
    };
  }

  render() {
    return <div {...this.props} style={{ backgroundImage: `url(${this.state.src || this.props.placeholder})` }} />;
  }
}
类LazyBackground扩展了React.Component{
状态={src:null};
componentDidMount(){
const{src}=this.props;
const imageLoader=新图像();
imageLoader.src=src;
imageLoader.onload=()=>{
this.setState({src});
};
}
render(){
返回;
}
}

您可以用

来调用它。根据Naoise的回答,这里有一个定制的React钩子:

const useProgressiveImage = src => {  
  const [sourceLoaded, setSourceLoaded] = useState(null)

  useEffect(() => {
    const img = new Image()
    img.src = src
    img.onload = () => setSourceLoaded(src)
  }, [src])

  return sourceLoaded 
}
用法:

const Component = (source, placeholder) => {
  const loaded = useProgressiveImage(source)

  return (
    <div style={{ backgroundImage: `url(${loaded || placeholder})` }} />
  )
}
const组件=(源,占位符)=>{
const load=useProgressiveImage(源)
返回(
)
}

具有如下功能组件:

function LazyBackground({src}) {
    const [source, setSource] = useState("preload.jpg")

    useEffect(() => {
        const img = new Image()
        img.src = src
        img.onload = () => setSource(src)
    }, [src])

    return(
        <div style={{backgroundImage: `url(${source})`}}></div>
    )
}
函数LazyBackground({src}){
const[source,setSource]=useState(“preload.jpg”)
useffect(()=>{
常量img=新图像()
img.src=src
img.onload=()=>setSource(src)
},[src])
返回(
)
}
用法:

<LazyBackground src={"https://example.com/your_image.jpg"}/>

为了延迟加载
背景图像
,您需要为加载任何带有
url
的文件的CSS属性创建样式表,因为您不希望这些图像延迟第一次内容绘制。 例如:

FirstModal.modules.less 此文件具有将首先加载的重要CSS属性

firstModalBackground.module.less 此文件将在关键CSS

出于演示目的,我将在这里使用React.Component,但是,如果您想尝试优化东西,也可以使用React.PureComponent(我测试过它,一切都很好)

firstModal.jsx
真的很酷!我用它来显示上传时的本地文件url,只有在从S3加载后才替换它。谢谢:)
<LazyBackground src={"https://example.com/your_image.jpg"}/>
.styles {
    &-container {
        position: absolute;
        width: 100%;
        height: 100%;
        display: flex;
        flex-direction: column;
        align-content: center;
        justify-content: center;
        align-items: center;
    }
}
.styles {
    &-container {
        background: url('../../images/code/code.jpg') no-repeat center center fixed;
        background-size: cover;
    }
}
const classNames = require('classnames');
const React = require('react)';
const {stylesContainer} = require('./firstModal.module.less');

class FirstModal extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            classNames: classNames([stylesContainer])
        };
    }

    async componentDidMount() {
        const backgroundImage = await import(
            './firstModalBackground.module.less'
        );
        this.setState({
            classNames: [
                classNames(this.state.classNames, [backgroundImage.stylesContainer]),
            ]
        });
    }

    render() {
        // console.log(this.state.classNames);
        return <div className={this.state.classNames}>It werks!</div>;
    }
}

module.exports = FirstModal;
    async componentDidMount() {
        const lowResolutionBackgroundImage = await import(
            '../greeting-page/firstModalLowResBackground.module.less'
        );
        const baseClass = this.state.classNames;
        this.setState({
            classNames: [
                classNames(baseclass,
                    lowResolutionBackgroundImage.stylesContainer),
                ]
            });
        const backgroundImage = await import(
            './firstModalBackground.module.less'
        );
        this.setState({
            classNames: [
                classNames(baseClass,
                    backgroundImage.stylesContainer),
            ]
        });
    }