abinas patra
abinas patra

Reputation: 389

Replace multiple strings within string with react jsx element

  1. I have a string called I want to order cheese chicken pizza..
  2. I want to replace cheese with <span style={{color: 'red'}}>cheese</span> and chicken with <span style={{color: 'green'}}>chicken</span>.
  3. So I expect a result like I want to order <span style={{color: 'red'}}>cheese</span> <span style={{color: 'green'}}>chicken</span> pizza.

In an array I have data like let arr = ['cheese', 'chicken']. I took the below approach:-

let text = "I want to order cheese chicken pizza."
arr.map(a=>{
  let findText = new RegExp(a, 'g');
  text = text.replace(findText, (match)=>(<span>{match}</span>))
});
return text;

I get the result I want to order [object object] [object object] pizza. I checked maximum solution is for replacing single same string. I want to achieve this because I will add eventListener to each span tag to get the details.

Can anyone help me out. Thnaks :)

Upvotes: 0

Views: 1016

Answers (2)

codemonkey
codemonkey

Reputation: 7905

The challenge, as outlined by Joans, is that you're trying to mix JSX and a string. There are, however, ways around it. The first thing you should do, is convert your array of strings to an object of elements. So this:

let arr = ['cheese', 'chicken']

Should be:

const Elems = {
  cheese: (
    <span
      style={{ color: "red", marginRight: "5px" }}
      onClick={() => alert("clicked cheese span")}
    >
      cheese
    </span>
  ),
  chicken: (
    <span
      style={{ color: "red", marginRight: "5px" }}
      onClick={() => alert("clicked chicken span")}
    >
      chicken
    </span>
  )
};

Notice how each span element has the onClick attached to them so you can catch the click event. You can add anything else you want.

Then, the idea is to break your text into an array such as:

["I", "want", "to", "order", "cheese", "chicken", "pizza."]

Replace those array elements (cheese and chicken) with the corresponding values inside your Elems object. And then render it. Easy! This function will do that for you:

const swapText = () => {
    const text_array = text.split(" ");
    const a = text_array.map((item) => {
      if (item in Elems) item = Elems[item];
      else item += " ";
      return item;
    });

    return a;
  };

Then just render it like so:

{swapText().map((item) => item)}

That's it. Here is a Sandbox for you: https://codesandbox.io/s/hardcore-lalande-vxwu6?file=/src/App.js

Upvotes: 2

Jonas
Jonas

Reputation: 1573

The issue is that you're dealing with strings and can't insert a span into a string. You could either deal in only JSX or only strings - which is better depends in part on your situation (not sure exactly how you plan on adding the event listener's on the spans). Here is what only strings would look like:

let arr = ['cheese', 'chicken']
let text = "I want to order cheese chicken pizza."
arr.map(a=>{
  let findText = new RegExp(a, 'g');
  text = text.replace(findText, (match)=>(`<span>${match}</span>`))
});
return text;

Upvotes: 1

Related Questions