использовать HTML-теги в переменной JS (react)

#html #reactjs #tags

#HTML #reactjs #Теги

Вопрос:

Я пытаюсь выяснить, упоминался ли пользователь в сообщении. Если это так, я хочу связать имя пользователя с профилем.

Что я пробовал:

   if (mentions.length === 1) {
    const splitSearch = '@'   mentions[0].user.name;
    const replaceWith =
      '<a href=profile/'  
      mentions[0].user._id  
      '>@'  
      mentions[0].user.name  
      '</a>';
    newText = text.split(splitSearch).join(replaceWith);

  }

...

return (
...
{mentions.length > 0 amp;amp; (
  <p id='text-container'>{newText}</p>
)}
  

Но я просто возвращаю теги в виде обычного текста:

 hi <a href=profile/5f1bd6c7d90cb03e845adbbf>@user1</a>. 
hello <a href=profile/5f30380288a63e001755401e>@user2</a>.
  

Нужно ли мне писать replaceWith const другим способом? Я пытался Link вместо a , но не смог заставить это работать.

Заранее спасибо!

Ответ №1:

React может отображать только компоненты JSX.

Вместо построения HTML-строки создайте массив дочерних элементов. Когда будет найдено упоминание, поместите <a> (элемент JSX, а не строку) в массив между его соседними дочерними элементами:

 const children = text.split(splitSearch);
// Insert an `<a>` between each element:
for (let i = children.length - 1; i > 0; i--) {
  const a = <a href={`profile/${mentions[0].user._id}`}>@{mentions[0].user.name}</a>;
  children.splice(i, 0, a);
}

// Then render:
{mentions.length > 0 amp;amp; (
  <p id='text-container'>{children}</p>
)}
  

Комментарии:

1. Спасибо за ваш ответ. У меня есть несколько вопросов. Почему вы используете «дочерние элементы. длина — 2»? Если бы кто-то набрал «привет @user1», это было бы просто 0, не так ли? Я пробовал как с, так и без -2. Оба раза я получаю обратно пустой массив после объединения.

2. Я все еще не могу заставить это работать. Когда я регистрирую «дочерние элементы» после объединения, у меня есть массив. Итак, это работает. Но {дочерние элементы} пусты. Поскольку объединение происходит внутри оператора if, мне нужно сказать что-то вроде «пусть children = []» перед этим, верно?

3. После того, как вы сгенерировали дочерний массив, вам нужно каким-то образом перенести его в раздел визуализации — будь то путем переназначения children или чего-то еще

4. это работает. большое спасибо. вы знаете, как я могу отобразить упоминания? итак, упоминается более одного пользователя, каждый пользователь получает a-tag?

5. Вы могли бы использовать .match вместо .split — сопоставлять все, что является упоминанием, или сопоставлять все, что не является упоминанием, чтобы разделить их, а затем использовать .map в массиве, чтобы превратить все упоминания в <a> s.

Ответ №2:

это неправильно.

Идея react не в том, чтобы «генерировать собственный HTML, как в вашем примере».

Вы должны использовать map внутри return (и генерировать Link для каждого элемента в массиве) следующим образом:

 return (
    {
        mentions.length > 0 amp;amp; (
            <p id='text-container'>
                {
                    mentions.map((m) => (
                       <Link key={m.user._id} to=`${m.user._id}`>
                         {m.user.name}
                       </Link>
                    ))
                }
            </p>
        )
    }
)
  

Комментарии:

1. Проблема с этим: упоминание находится внутри текста. Например, «Привет @user1, что я хотел тебе сказать …». Когда я просто сопоставлю упоминания, я не смогу просто связать имя пользователя, не так ли?