DEV Community

Everaldo Junior
Everaldo Junior

Posted on

1 1

How to load local dynamic images with html in React Native

First we will need to use react-native-render-html

(I like it because it doesn’t use WebView, and WebView for this kinda thing is bad.)

But there is a problem, this lib doesn’t have a way to load local images out of the box. For that** you need to create a custom image tag and add it to your HTML component**

Like this:

const htmlContent = ` 
  <h1>This HTML snippet is now rendered with native components !</h1>
  <img source="./src/assets/michael.jpg"/>
  <h2>Enjoy a webview-free and blazing fast application</h2>
  <em>Some random sentence!</em>
`;


        <HTML
          renderers={{
            img: (attribs) => {
              const imagePath = attribs.source;
              console.log(imagePath);
              return (
                <Image
                  key={attribs.source}
                  style={styles.imageContainer}
                  source={require('./src/assets/michael.jpg')}
                />
              );
            },
          }}
          source={{html: htmlContent}}
          contentWidth={contentWidth}
        />
Enter fullscreen mode Exit fullscreen mode

Here i’m creating a custom tag named img inside renderers prop and defining it as an component with an image path that i have selected.

And that’s the result:

But the main problem isn’t solved, our goal is to render local images dynamically using that custom tag that we’ve created.

After this maybe you’re thinking:

-“Just pass the image path as a prop to the <img/> tag and voila, you’re done!”

OK, that sounds right, but how do I pass the image path that I want our custom tag to render?

I added a source prop with the image path in <img> tag.

<img source="./src/assets/michael.jpg"/>
Enter fullscreen mode Exit fullscreen mode

And i am getting it inside our img function adding **attribs **as a parameter

Now i can access the image path using attribs.source

const htmlContent = ` 
  <h1>This HTML snippet is now rendered with native components !</h1>
  <img source="./src/assets/michael.jpg"/>
  <h2>Enjoy a webview-free and blazing fast application</h2>
  <em>Some random sentence!</em>
`;


        <HTML
          renderers={{
            img: (attribs) => {
              const imagePath = attribs.source;
              console.log(imagePath);
              return (
                <Image
                  key={attribs.source}
                  style={styles.imageContainer}
                  source={require('./src/assets/michael.jpg')}
                />
              );
            },
          }}
          source={{html: htmlContent}}
          contentWidth={contentWidth}
        />
Enter fullscreen mode Exit fullscreen mode

This will output in the console:

"./src/assets/michael.jpg"
Enter fullscreen mode Exit fullscreen mode

Now, if we try to change line 18 like this:

require('./src/assets/michael.jpg);

to

require(imagePath);
Enter fullscreen mode Exit fullscreen mode

We are going to get this error:

[Error: TransformError App.js: App.js:Invalid call at line 31: require(imagePath)]
Enter fullscreen mode Exit fullscreen mode

That’s because all the imports have to be a string, not a dynamic expression.

Maybe now you’re thinking:

“-If he is writing a post on Medium its because there’s is a way to import dynamic imports inside require, right?”

Well, no…

Let me show you what we are going to do:

One thing we know for sure, you can normally import images like this:

 const imagesList = {
    dwight: require('./src/assets/dwight.jpg'),
    michael: require('./src/assets/michael.jpg)
  }

const htmlContent = ` 
  <h1>This HTML snippet is now rendered with native components !</h1>
  <img source="./src/assets/michael.jpg"/>
  <h2>Enjoy a webview-free and blazing fast application</h2>
  <em>Some random sentence!</em>
`;


        <HTML
          renderers={{
            img: (attribs) => {
              const imagePath = attribs.source;
              return (
                <Image
                  key={attribs.source}
                  style={styles.imageContainer}
                  source={imagesList[imagePath]}
                />
              );
            },
          }}
          source={{html: htmlContent}}
          contentWidth={contentWidth}
        />
Enter fullscreen mode Exit fullscreen mode

So, i’m creating an object with all my images and it’s requires as properties of that object.

const imagesList = {
    dwight: require('./src/assets/dwight.jpg'),
    michael: require('./src/assets/michael.jpg)
  }
Enter fullscreen mode Exit fullscreen mode

Now i can finally pass the image that we want to render in the source property in our custom tag.

<img source="michael"/>
Enter fullscreen mode Exit fullscreen mode

We also need to modify the Image component to something like this:

<Image
   key={attribs.source}
   style={styles.imageContainer}
   source={imagesList[imagePath]}
 />
Enter fullscreen mode Exit fullscreen mode

Now, if i change

<img source="michael"/>

to

<img source ="dwight"/> 
Enter fullscreen mode Exit fullscreen mode

Th will be the result:

Conclusion

The best way to implement this solution is to isolate your imageList variable in another file, and add each one of your images and it’s paths manually or you can create a script that does all the hard job for you (like i did).

You can learn how to create this script on this tutorial.

You can find the project source code here

I hope this has helped you ;)

Heroku

Deliver your unique apps, your own way.

Heroku tackles the toil — patching and upgrading, 24/7 ops and security, build systems, failovers, and more. Stay focused on building great data-driven applications.

Learn More

Top comments (0)

Jetbrains image

Build Secure, Ship Fast

Discover best practices to secure CI/CD without slowing down your pipeline.

Read more

👋 Kindness is contagious

Engage with a wealth of insights in this thoughtful article, valued within the supportive DEV Community. Coders of every background are welcome to join in and add to our collective wisdom.

A sincere "thank you" often brightens someone’s day. Share your gratitude in the comments below!

On DEV, the act of sharing knowledge eases our journey and fortifies our community ties. Found value in this? A quick thank you to the author can make a significant impact.

Okay