Terence Chow
Terence Chow

Reputation: 11173

Webpack require dynamic image in a React component

I am using React with Webpack.

I have a React Component that takes a prop which is a url and displays the image.

Since React won't know the image url until runtime, can webpack still 'require' the image url?

import React, {Component} from 'react'

export default class Episode extends Component {

    constructor(props){
        super(props)
    }

    render(){

        let imageStyle = {backgroundImage: 'url(' + this.props.episode.url +')'}

    return (
            <div className="episode">
                    <div className="image" style={imageStyle}>
                        <h2>{this.props.episode.category}</h2>
                    </div>
                <h3>Episode {this.props.episode.number}</h3>
            </div>
        )

    }
}

For reference, my images are located in:

src/assets/images

and my webpack is building to dist

Upvotes: 5

Views: 2286

Answers (2)

mjudd
mjudd

Reputation: 21

For reference, Jumoels answer was almost there but you can't do an import statement inside a componentWillMount.

My Solution to this was as follows:

class YourComponent extends Component {
    constructor(props){
        super(props);
        
        this.state = {
            image: ""
        };
    }

    componentWillMount(){
        this.state.image = require('../../public/assets/img/' + this.props.img);
    }

    render() {
        return(
           <img src={this.state.image}/>
        )
    }
}

Upvotes: 2

jumoel
jumoel

Reputation: 1790

You can use import() to load the images dynamically. Then, you can do something like the following in componentDidMount:

import('path/to/images/' + this.props.episode.url).then(function(image) {
    this.setState({ image: image });
}).catch(function(err) {
    // Do something
});

In your render-function you can then render a placeholder image, for instance a transparent gif, until this.state.image contains something valid.

render() {
    const imageSource = this.state.image
        ? this.state.image
        : "data:image/gif;base64,R0lGODlhAQABAAAAACw=";

    return <img src={imageSource} />;
}

Upvotes: 1

Related Questions