4

I'm trying to dynamically load an image in some React Component. I'm using require instead of simply passing the paths in order to improve performance.

I gathered I could use an inline require and it does work. However, when I try to pass as a prop instead, I get errors.

What am I doing wrong?

EDIT: Turns out both work, I was doing something else wrong which was throwing the error. (Bonus question still applies tho)

import React from 'react';

// This works
export SomeComponent = () => (
  <div>
    <img src={require(`../images/my-logo.svg`)} />
  </div>
)

// This works too!
export SomeComponent = ({image}) => (
  <div>
    <img src={require(`../images/${image}`)} />
  </div>
)

<SomeComponent image="my-logo.svg" />

Bonus question: Can this be done with ES6 import vs CommonJs require?

2
  • Did you create your project with create-react-app? Commented May 19, 2018 at 16:12
  • Nope. I'm actually using GatsbyJS. Commented May 19, 2018 at 16:16

2 Answers 2

3

Not sure if it is going to work but you can try:

class Image extends React.Component {
  constructor(props) {
    super(props)
    this.state = { src: null }
  }

  componentDidMount() {
    this.loadImage(this.props.name)
  }

  componentDidUpdate(prevProps) {
    if(prevProps.name !== this.props.name) {
      this.loadImage(this.props.name)
    }
  }

  loadImage(name) {
    import(`../images/${name}`)
      .then(image => {
        console.log(image); // this may be object with image inside...
        this.setState({ src: image })
      })
  }

  render() {
    return <img src={this.state.src} />
  }
}
Sign up to request clarification or add additional context in comments.

2 Comments

This may work though it seems a little heavy handed.
that's because of dynamic imports use Promises.
3

For React 16+, @Tomasz Mularczyk's answer needs a small tweak:

loadImage(name) {
    import(`../images/${name}`)
      .then(image => {
        console.log(image); // This will show an object with a `default` property as the image you imported
        this.setState({ src: image.default })
      })
 }

Full Source:

class Image extends React.Component {
  constructor(props) {
    super(props)
    this.state = { src: null }
  }

  componentDidMount() {
    this.loadImage(this.props.name)
  }

  componentDidUpdate(prevProps) {
    if (prevProps.name !== this.props.name) {
      this.loadImage(this.props.name)
    }
  }

  loadImage(name) {
    import(`../images/${name}`)
      .then(image => {
        console.log(image); // This will show an object with a `default` property as the image you imported
        this.setState({ src: image.default })
      })
  }

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.