Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

222
Vistas
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 Respuestas
Responde la pregunta

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 Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda