Введение

В этой статье я расскажу, как реализовать компонент ввода React, который поддерживает:
i. Упоминание пользователей или элементов и отображение данных, сохраненных в БД.
ii. Выбор и обнаружение эмодзи.

Итак, вначале я обнаружил, что у меня есть две задачи, которые нужно выполнить, и лучше работать над каждой задачей отдельно. Чтобы получить такой компонент

А затем извлеките данные и отобразите их следующим образом

1. Упоминания

Упоминание пользователей

Проведя свое исследование, я обнаружил, что наиболее популярными пакетами React, используемыми для упоминания пользователей, являются Draft.js с его плагинами и React-Mentions. Причина, по которой я выбрал React-Mentions, заключается в том, что это проще, когда дело доходит до

  1. Формат комментария, сохраняемого пакетом.
  2. Сохранение упоминаний в БД.
  3. Отображение сохраненных комментариев из БД.
  4. Упоминания о стилях раскрываются.

Реализация

Первый шаг: установите пакеты React-Mentions и Substyle-jss.

Второй шаг: добавьте пакеты в компонент CommentInput

import { Mention, MentionsInput } from “react-mentions”;
import { StylesViaJss } from “substyle-jss”;

Третий шаг: добавьте импортированные компоненты

<StylesViaJss>
  <MentionsInput
    value={comment}
    onChange={event => setComment(event.target.value)}
    className="mentions"
    classNames={Style}
    placeholder="Leave a comment..."
    allowSuggestionsAboveCursor={true}
  >
    <Mention data={users} className={Style.mentions__mention} />      
  </MentionsInput></StylesViaJss>

Вышеупомянутая часть содержит несколько переменных

  1. comment: строка, которая обрабатывает ваш текст.

    Упоминание комментария выглядит так @ [display] [id]
    так что Hey Aly Seoudi = ›Hey [Aly Seoudi] [xxx]
const [comment, setComment] = useState(“”);

2. classNames: стили для внутренних компонентов MentionsInput.

classNames={Style}

в полеcodeandbox в конце есть образец компонента стиля.

3. Пользователи: это массив объектов, которые вы хотите упомянуть, состоящий из Id и Display.

const users = [
{id: "walter",display: "Walter White"},
{id: "jesse",display: "Jesse Pinkman"}
]

Четвертый шаг: добавьте кнопку, отправляющую данные в БД.

<div
  className="comment-input-container px-2 row col-12 mx-auto"
  style={comment ? { border: "1px solid #71cee3" } : {}}
>
  <div className="col-11 px-0">
    <MentionsInput
      value={comment}
      onChange={handleChange}
      className="mentions"
      classNames={Style}
      placeholder="Leave a comment..."
      allowSuggestionsAboveCursor={true}
    >
      <Mention data={members} className={Style.mentions__mention} />   
    </MentionsInput>
  </div>
  <div className="col-1">
    <button
      className="send-text"
      style={comment ? { color: "#3B5E66" } : {}}
      onClick={handleSendClick}
    >
      Send
    </button>
  </div>
</div>
const handleSendClick = () => {
   API.Call(comment);
}

Извлечение данных

Получить данные здесь довольно просто, все, что вам нужно, это компонент, содержащий абзац, и метод, который обрабатывает комментарий, полученный из БД.

Параграф:

<p
className="d-inline comment-paragraph-text"
dangerouslySetInnerHTML={{
__html: text.replace(/\n\r?/g, "<br />"),}}
/>

Метод:

const [text, setText] = useState("");
useEffect(() => {
 if (comment!== "") {
 let regex = /@\[.+?\]\(.+?\)/gm;
 let displayRegex = /@\[.+?\]/g;
 let idRegex = /\(.+?\)/g;
 let matches = comment.match(regex);
 let arr = [];
 matches &&
 matches.forEach((m) => {
  let id = m.match(idRegex)[0].replace("(", "").replace(")", "");
  let display =    
       m.match(displayRegex)[0].replace("@[","").replace("]","");
  arr.push({ id: id, display: display });
 });
let newComment = comment.split(regex);
 let output = "";
 for (let i = 0; i < newComment.length; i++) {
   const c = newComment[i];
   if (i === newComment.length - 1) 
     output += c;
   else
     output +=
       c + `<a href="/People/${arr[i].id}">${arr[i].display}</a>`;
 }
 setText(output);
}}, [comment]);

И это ссылка на песочницу для упоминания.

2. Смайлы

Выполнение

  1. Установить Эмодзи-Март

2. Добавьте пакеты в компонент CommentInput.

import { NimblePicker, emojiIndex } from "emoji-mart";
import "emoji-mart/css/emoji-mart.css";
import data from "emoji-mart/data/google.json";

3. Добавьте импортированные компоненты.

<NimblePicker
 onSelect={(emoji)=> setComment(`${comment} ${emoji.native}`)}
 showSkinTones={false}
 emojiTooltip={false}
 showPreview={false}
 sheetSize={32}
 data={data}
/>

Здесь есть много вариантов, которые вы можете проверить в Github Repo.

Приведенный выше фрагмент кода содержит объект эмодзи, из которого мы выбираем собственное свойство, которое выглядит как

{
 id: 'smiley',
 name: 'Smiling Face with Open Mouth',
 colons: ':smiley:',
 text: ':)',
 emoticons: [
  '=)',
  '=-)'
 ],
 skin: null,
 native: '😃'
}

4. Кнопка «Добавить» для переключения видимости компонента средства выбора смайлов путем добавления ссылки для диапазона, содержащего средство выбора смайлов.

const [showEmojis, setShowEmojis] = useState(false);
{showEmojis ? (
 <span className={Style.emoji__picker} ref={emojiPicker}>
<NimblePicker
   onSelect={handleSelectEmoji}
   showSkinTones={false}
   emojiTooltip={false}
   showPreview={false}
   sheetSize={32}
   data={data}
  />
</span>
) : (
<button
 className={Style.emoji__button}
 onClick={()=>setShowEmojis(true)}
>
 {String.fromCodePoint(0x1f60a)}
</button>
)}

Добавить прослушиватель событий для обработки щелчков вне средства выбора и закрыть его.

useEffect(() => {
 function handleClickOutside(event) {
  if (
   emojiPicker.current&&!emojiPicker.current.contains(event.target))     
  {
    setShowEmojis(false);}
  }
  document.addEventListener("mousedown", handleClickOutside);
  return () => {
   document.removeEventListener("mousedown", handleClickOutside);
  };
}, [emojiPicker]);

Обнаружение распространенных эмодзи по тексту

При обработке изменения текста в MentionsInput вместо того, чтобы просто устанавливать комментарий для event.target.value, я запускал выражение регулярного выражения, чтобы сначала обнаружить обычно используемые Emojis

onChange={handleChange}
const handleChange = (event) => {
 let text = colonsToUnicode(event.target.value);
 onChange(text);
};
const colonsToUnicode = (text) => {
 const colonsRegex = new RegExp("(^|\\s):([)|D|(|P|O|o])+", "g");
 let newText = text;
 let match = colonsRegex.exec(text);
 if(match!==null) {
  let colons = match[2];
  let offset = match.index + match[1].length;
  newText = 
            newText.slice(0, offset) + 
            getEmoji(colons) + 
            newText.slice(offset + 2);
 }
 return newText;
};
const getEmoji = (emoji) => {
 let emoj;
 switch (emoji) {
  case "D":
   emoj = emojiIndex.search(":)")[1].native;
   break;
  case ")":
   emoj = emojiIndex.search(":)")[0].native;
   break;
  case "(":
   emoj = emojiIndex.search(":(")[0].native;
   break;
  case "P":
   emoj = emojiIndex.search(":P")[0].native;
   break;
  and so on...
  default:
   emoj = "";
 }
 return emoj;
};

Последним шагом было добавление стиля, представленного в ссылке на код и ящик.

Спасибо

Вот как я реализовал компонент ввода чата / комментария с React-Mentions и Emoji-Mart.

Не стесняйтесь обращаться ко мне, если у вас есть какие-либо вопросы относительно этой статьи или любой другой темы для обсуждения.