Ghadir
Ghadir

Reputation: 537

Reactjs: How to import an image from a variable path

I am relatively new to Reactjs so I might be missing something obvious:

I have a component (DisplayFlags.js) that displays country flags along with country names depending on a previously chosen continent. I have everything set up: all possible flag images exist locally, I also have a js object called 'myCountries' that maps each continent to its countries, and each country to its name + local flag image name. Here is a part of it:

const myCountries ={
    "north-america": {
        "US": {
            "name": "United States",
            "picPath": "flag-of-United-States.png"
        },
        "UM": {
            "name": "United States Minor Outlying Islands",
            "picPath": "flag-of-United-States-Minor-Outlying-Islands.png"
        },
        "CA": {
            "name": "Canada",
            "picPath": "flag-of-Canada.png"
        },
        "MX": {
            "name": "Mexico",
            "picPath": "flag-of-Mexico.png"
        },
//etc
},
"south-america":{
  "AR": {
            "name": "Argentina",
            "picPath": "flag-of-Argentina.png"
        },
        "BO": {
            "name": "Bolivia",
            "picPath": "flag-of-Bolivia.png"
        },
//etc
}
}

What I am planning to do: loop through all the countries of a previously selected continent, and pass the "name" and "picPath" as props to another component, SingleCountry.js, who in turn displays them. My problem is with importing: I usually just write (example):

import randomImage from '../../img/icons/some-image-name.png'

And then use randomImage as the src of an img element in my component. In this case, is there a way to import an image from a path that is passed in props? Something like:

import flagImage from "../../img/flags/" + this.props.picPath

I understand that the above doesn't work because imports work outside of a component, and they don't have access to any kind of props. Can I import inside a component? Or should I totally drop this and import images in bulk in DisplayFlag.js then pass images one by one into SingleCountry.js?

Upvotes: 4

Views: 8045

Answers (3)

Olaf Erlandsen
Olaf Erlandsen

Reputation: 6036

You can try with:

Using import for browser and nodejs

const picture = (await import(`../path/to/file/${this.props.picPath}`)); // this is async

Using require for browser and nodejs

const picture = require(`../path/to/file/${this.props.picPath}`); // this is sync

Using readFileSync from fs only for nodejs

const fs = require('fs')
// or: import fs from 'fs'

const file = fs.readFileSync(`../path/to/file/${this.props.picPath}`).toString()

Using readFile from fs only for nodejs

const fs = require('fs')
// or: import fs from 'fs'
const file = (await fs.readFile(`../path/to/file/${this.props.picPath}`)).toString()

Tip #1:

When you using require, it only can handle json and js files, but when you using import, it can handle svg, and other stuff. But you can apply some trick like:

// in tsconfig.json
"include": [
    "./declarations.d.ts",
],
// in declaration.d.ts
declare module '*.png';

Tip #2:

When you wanna import images like png, you should be define how it work with this:

declare module "*.png" {
  const value: any;
  export default value;
}

Tip #3 In javascript you can use Template Literals using `` and ${}.

const name = "John"
console.log(`Hello ${name}`);

Upvotes: 3

Adithya
Adithya

Reputation: 1728

You could have a file import all the images like

//images/index.js

import image1 from './image1.png'
import image2 from './image2.png'
.
.
export default {
image1,
image2,
.
.
}

you can access images dynamically from the object exported from here

import images from './images/index.js'
images['image1'] 

// or dynamically
let name = 'image2'
images[name]

Upvotes: 5

Czcibor
Czcibor

Reputation: 66

What first coming to my head is to create stateless component which will take your flag object and show tag with specific path. It won't import as react suggest but it will do the job :) Instead if u really want use react approches you could use require instead of import, checkout below question, I think it will satisfying you:

react native use variable for image file

Upvotes: 1

Related Questions