Skip to content
Advertisement

How to use an image from a path in React Typescript without import or require?

I have a Typescript program with a readable name : img_path mapping saved in a .ts file. Based on certain criteria, I want to pass in an individual entry to a component which will then display the readable name as a title and under it show the image saved in img_path. I can do this in Javascript fine, but for some reason in Typescript, it won’t let me use require. The solution I’m used to would be something like:

<img src={require(props.imgPath)} />

However, in Typescript that gives me the error: Uncaught ReferenceError: require is not defined

From what I’ve researched, I should be using import, something like:

import myi from "src/assets/myImage.png"

and then in my render function, do

<img src={myi} />

However, since imports have to be done at the top of the file, you can’t use variables passed into the component. So that won’t work for a dynamically decided pairing. (One option would be to import every individual image, but there are a lot of images, and if I change the mapping at all, I would have to find all component files and update them there too).

How can I pass a string with the image path to a Typescript component and have that component display the image, without using import or require?

Advertisement

Answer

The most consolidated way I’ve found to do this is to create a separate images.ts file whose content is of the form:

import img0 from "filepath0"
import img1 from "filepath1"
...
import imgN from "filepathN"

export const images : {[key:string] : any} = {
    "filepath0" : img0,
    "filepath1" : img1,
    ...
    "filepathN" : imgN,
}

Then in any file where you want to use the images, you call:

import { images } from "../images";

Then you can just pass the path into the images object (e.g. images[props.imgPath]) to get the actual image. For example:

// RENDER
return <img src={images[props.imgPath]} />;

(Note: Alternatively, you can reference an image using just the image name rather than its full path by storing the name as the key in the images object rather than the path itself)

— Extra —

If you have a lot of images, you don’t want to have to write out the images.ts file by hand. I used the following to make it easier to create.

Part 1: Get image file names

In the folder containing your images (and hopefully just your images), open a command terminal and run:

dir /b /a:-d /o:n > filelist.txt

(The dir gives a list of files, the /b /a:-d /o:n gives just the name not any other details such as size or date, and > filelist.txt saves the output to a txt file rather than the terminal itself.)

Open the file and remove “filelist.txt” from it any any other name that isn’t an image.

Part 2: Get list of imports

In the folder where “filelist.txt” is saved, run the following using Python (either using python in a command terminal or a python IDE):

with open("filelist.txt") as f:
    names = [x.strip() for x in f.readlines()]

This creates a list names of all the image file names (with the n at the end of each line in the original text file removed).

Create a new list that’s the full paths for the image as react would want to see it:

paths = [PATH + name for name in names]

What you put in PATH will be the same for each image. E.g.

paths = ["src/MyApp/assets/" + name for name in names]

Then do:

for i in range(len(names)):
    print ("import img" + str(i) + " from "" + paths [i] + """)

This will print out all the import img0 from "filepath0" lines you need for your react images file. Copy them into your react file.

Part 3: Get mapping object

Type export const images : {[key:string] : any} = in your react file.

Then run the following in your python program and paste the output in your react file after the equal sign:

dict([(paths[i], "img" + str(i)) for i in range(len(paths))])

This outputs the dictionary (Javascript object) comprised of "filepath0" : img0" statements.

If you want each "filepath0" : img0" to be on its own line instead of one after another, use python print statements instead:

print ("{")
for i in range(len(paths)):
    print("    "" + paths[i] + "" : img" + str(i) + ",")
print ("}")

Copy the output into your react file, being sure to delete the , after the very last "filepath0" : img0" line.

User contributions licensed under: CC BY-SA
6 People found this is helpful
Advertisement