React - Replace substring with image

I have been racking my brain on this all day and haven’t come to a solution yet.

I am attempting to replace multiple substrings with an image tag and render it.
The issue I am running into is getting the html image tag to render not as a string.

Here are the basics of my program:

render(){

 var inputMsg = 'Hello everyone! smile this is an example frown'

 var imageID = {"smile" : "1", "frown" : "2"}

 var imageNames = ["smile", "frown"]

 let regex = new RegExp(imageNames.join('|'), 'gi')

 var result = inputMsg.replace(regex, (match)=>{
       return <img ID={imageID[match]} src="smile.png"/>
 })

 return(
      {result}
 )

}

The problem I am running into is the rendering of “result” in my react component is “[object Object]”.

Does anyone know how to get my image tag to render as an image?

Try returning a string in the callback like:

var result = inputMsg.replace(regex, (match)=>{
    return `<img ID=${imageID[match]}  src="smile.png"/>`
})

and then render it inside another element using dangerouslySetInnerHTML attribute like:

  return <div  dangerouslySetInnerHTML={{ __html: result }} />;

Not sure of the exact use case here, is it just for the id attribute?

If so wouldn’t it make more sense to just use the imageID[match] as the return and replace the id value with that in the JSX?

Example
export default function App() {
  const inputMsg = "Hello everyone! smile this is an example frown";
  const imageID = { smile: "1", frown: "2" };
  const imageNames = ["smile", "frown"];

  const regex = new RegExp(imageNames.join("|"), "gi");

  const result = inputMsg.replace(regex, (match) => {
    return imageID[match];
  });

  return (
    <div className="App">
      <img id={result} src="https://via.placeholder.com/400" alt="" />
    </div>
  );
}

It would be used to determine the source in the end. But the main issue is inserting an image tag and having it render as one. I believe I’ve come up with a solution.

When you say source, you mean the image source as in the value for the src attribute? If so the same would apply, calculate the final URL value and use that for the src value.

All you are doing is replacing attribute values, or am I missing something?

Not quite. I am taking a string “this is my string smile” and wanting an output of “this is my string :slight_smile:
so it has to be a dynamic source, but it also has to replace the string with an image tag

I’m really not sure I understand what you are trying to do.

Why would you need to create the JSX element outside the render/return? The element is fixed, it’s an image element (or whatever element), the data used on it for its attributes can be dynamic.

I’ve come up with a bit of a complex solution for this. It seems that when the tag is rendered from an array using the .map() function it will produce the correct results

var inputMsg = 'Hello everyone! smile this is an example frown'

                var imageID = {"smile" : "1", "frown" : "2"}
                var imageNames = ["smile", "frown"]

                let splitCode = [inputMsg]

                imageNames.forEach(emote => {

                    splitCode.forEach((part)=>{

                        let index = splitCode.indexOf(part)

                            if(typeof part === 'string'){

                                part = part.split(emote)

                                

                                if(part.length > 1){

                                    let imgTag = <img id={imageID[emote]} src={smile.png}/>

                                    let i = 1

                                    while (i < part.length) {
      part.splice(i, 0, imgTag);
      i += 2;
}

                                }

                            } else {

                                part = [part]

                            }

                        

                            splitCode.splice(index, 1, ...part)

                    })

                })

render(){

let result = splitCode.map((el)=>{
     return el
})

return(
     <div>
          {splitCode}
     </div>
)
}

I looked into the dangerouslySetInnerHTML option but from other forums was told to stay away from using it. Mostly because the input string will be sent by the user who can input anything.

dangerouslySetInnerHTML is dangerous and I am glad you bothered to look it up, that is why it has been named so but sometimes it can be the only way out. XSS attacks due to use of innerHTML occur if you are rendering content from user input as HTML. I don’t think it really is dangerous if you are rendering a string hard coded by you.