Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

223
Views
How to replace text with substitute that contains JSX code?
interface ICard {
  content: string,
  blanks: Array<{word: string, hidden: boolean}>
}
  function processCards():Array<any>{
    if (cards !==null ){
      const text = cards.map((card,cardIndex)=>{
        var content = card.content
        card.blanks.map((blank,blankIndex)=>{
          // replace content
          const visibility = (blank.hidden)?'hidden':'visible'
          const click_blank = <span className={visibility} onClick={()=>toggleBlank(cardIndex,blankIndex)}>{blank.word}</span>
          content = content.replace(blank.word,click_blank) 
        })  
        return content
      })
      return text
    } else {
      return []
    }
  }

I have an array of objects of type ICard. Whenever card.blanks.word appears in card.content, I want to wrap that word in tags that contain a className style AND an onClick parameter.

It seems like I can't just replace the string using content.replace like I've tried, as replace() does not like the fact I have JSX in the code.

Is there another way to approach this problem?

about 4 years ago · Juan Pablo Isaza
1 answers
Answer question

0

You need to construct a new ReactElement from the parts of string preceding and following each blank.word, with the new span stuck in the middle. You can do this by iteratively building an array and then returning it wrapped in <> (<React.Fragment>). Here's a (javascript) example:

export default function App() {
  const toggleBlankPlaceholder = (cardIndex, blankIndex) => {};
  const cardIndexPlaceholder = 0;
  const blanks = [
    { word: "foo", hidden: true },
    { word: "bar", hidden: false },
  ];
  const content = "hello foo from bar!";

  const res = [content];
  for (const [blankIndex, { word, hidden }] of blanks.entries()) {
    const re = new RegExp(`(.*?)${word}(.*)`);
    const match = res[res.length - 1].match(re);
    if (match) {
      const [, prefix, suffix] = match;
      res[res.length - 1] = prefix;
      const visibility = hidden ? "hidden" : "visible";
      res.push(
        <span
          className={visibility}
          onClick={() =>
            toggleBlankPlaceholder(cardIndexPlaceholder, blankIndex)
          }
        >
          {word}
        </span>
      );
      res.push(suffix);
    }
  }
  return <>{res}</>;
}

The returned value will be hello <span class="hidden">foo</span> from <span class="visible">bar</span>!

A couple of things:

  1. In your example, you used map over card.blanks without consuming the value. Please don't do that! If you don't intend to use the new array that map creates, use forEach instead.
  2. In my example, I assumed for simplicity that each entry in blanks occurs 0 or 1 times in order in content. Your usage of replace in your example code would only have replaced the first occurrence of blank.word (see the docs), though I'm not sure that's what you intended. Your code did not make an ordering assumption, so you'll need to rework my example code a little depending on the desired behavior.
about 4 years ago · Juan Pablo Isaza Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!