Введение
В этой статье я расскажу, как реализовать компонент ввода React, который поддерживает:
i. Упоминание пользователей или элементов и отображение данных, сохраненных в БД.
ii. Выбор и обнаружение эмодзи.
Итак, вначале я обнаружил, что у меня есть две задачи, которые нужно выполнить, и лучше работать над каждой задачей отдельно. Чтобы получить такой компонент
А затем извлеките данные и отобразите их следующим образом
1. Упоминания
Упоминание пользователей
Проведя свое исследование, я обнаружил, что наиболее популярными пакетами React, используемыми для упоминания пользователей, являются Draft.js с его плагинами и React-Mentions. Причина, по которой я выбрал React-Mentions, заключается в том, что это проще, когда дело доходит до
- Формат комментария, сохраняемого пакетом.
- Сохранение упоминаний в БД.
- Отображение сохраненных комментариев из БД.
- Упоминания о стилях раскрываются.
Реализация
Первый шаг: установите пакеты 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>
Вышеупомянутая часть содержит несколько переменных
- 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. Смайлы
Выполнение
- Установить Эмодзи-Март
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.
Не стесняйтесь обращаться ко мне, если у вас есть какие-либо вопросы относительно этой статьи или любой другой темы для обсуждения.