Commenting on threads and messages was once fairly messy previous to the introduction of @point out
functionalities. Although you could possibly ship a message in a thread, there was usually no method of figuring out who the message was for, and there was no approach to interact those that weren’t already concerned within the dialog.
With the introduction of @point out
, you’ll be able to point out pals (or well-meaning social media specialists) and invite them to hitch the dialogue.
You can also discover kinds with @point out
functionalities in varied functions like Fb, Dropbox, WhatsApp, and Gmail.
This text will take a look at constructing a kind with the @point out
performance included in React. We are going to particularly be working with the react-mentions
package deal.
You could find the entire code for this tutorial in my Github repo. Let’s get began!
Let’s begin by creating a brand new React app with the command under:
npx create-react-app react-mentions
In case you are utilizing Yarn, run the next command:
yarn create react-app react-mentions
I’ll be utilizing Yarn for the remainder of this tutorial.
Subsequent, set up the react-mentions
package deal as follows:
yarn add react-mentions
The react-mentions
package deal exports two React elements for rendering mentions: the MentionsInput
part and the Point out
part. MentionsInput
is the principle part used to render the textual content space management and may take a number of Point out
elements as kids.
The Point out
part represents a knowledge supply for a category of mentionable objects, together with customers, points, and extra.
Utilizing the MentionsInput
and Point out
elements
Let’s implement react-mentions
into our software. Head over to the App.js
file and exchange your entire code with the code block under:
import { Point out, MentionsInput } from "react-mentions"; operate App() { return ( <div> <h2>Let's get began</h2> <MentionsInput> <Point out /> </MentionsInput> </div> ); } export default App;
After we begin up the event server with yarn begin
, we should always get an enter field like within the picture under:
Subsequent, we are going to create an array of dummy knowledge that’ll be offered to the Point out
part. The information should have id
and show
as particular keys.
We additionally have to create a state occasion. This can be used to bind the state of our software to the values coming from the info after which move it to the MentionsInput
part.
Copy and paste the code under into the App.js
file:
Extra nice articles from LogRocket:
operate App() { const [value, setValue] = useState(""); const customers = [ { id: "isaac", display: "Isaac Newton", }, { id: "sam", display: "Sam Victor", }, { id: "emma", display: "[email protected]", }, ]; ... }
We created a state variable and consumer array based mostly on the code block above. The consumer array comprises objects with id
and show
parameters. These are the parameters wanted to populate the react-mentions
part.
Now, let’s replace the return()
assertion with the code under:
return ( <div className="App"> <MentionsInput worth={worth} onChange={(e) => setValue(e.goal.worth)}> <Point out knowledge={customers} /> </MentionsInput> </div> );
We’re utilizing the MentionsInput
tag that takes within the worth
prop. We’re then setting the state worth with the onChange
prop. With all this achieved, we should always be capable to obtain this:
Styling react-mentions
elements
our progress above, chances are you’ll discover that our part seems a bit misplaced. We are able to repair it by customizing with types.
Create a mentionStyles.js
file within the src
folder and paste the code under:
export default { backgroundColor: "#cee4e5", };
Create a mentionsInputStyles.js
file within the src
folder as nicely and paste the code block under into it:
export default { management: { backgroundColor: '#fff', fontSize: 16, // fontWeight: 'regular', }, '&multiLine': { management: { fontFamily: 'monospace', minHeight: 63, }, highlighter: { padding: 9, border: '1px strong clear', }, enter: { padding: 9, border: '1px strong silver', }, }, '&singleLine': { show: 'inline-block', width: 180, highlighter: { padding: 1, border: '2px inset clear', }, enter: { padding: 1, border: '2px inset', }, }, recommendations: { checklist: { backgroundColor: 'white', border: '1px strong rgba(0,0,0,0.15)', fontSize: 16, }, merchandise: { padding: '5px 15px', borderBottom: '1px strong rgba(0,0,0,0.15)', '¢ered': { backgroundColor: '#cee4e5', }, }, }, }
Head again to App.js
and import the model:
import mentionStyle from "./mentionStyle"; import mentionsInputStyle from "./mentionsInputStyle";
Now, replace the elements:
<div className="App"> <MentionsInput model={mentionsInputStyle} worth={worth} onChange={(e) => setValue(e.goal.worth)}> <Point out model={mentionStyle} knowledge={customers} /> </MentionsInput> </div>
We’ve up to date our elements by including the model prop and setting it to the imported model.
With our progress to this point, we’ve achieved a pleasant, personalized Point out
performance in our app!
Exploring different functionalities in react-mentions
The react-mentions
package deal comes with many customizable options, so let’s have a look into a few of them!
singleLine
enter
singleLine
enter known as after we need our enter to be a single line of textual content moderately than the default textual content space. You’ll be able to see this within the code under:
return ( <div className="App"> ... <h2>Utilizing a Single line Enter</h2> <MentionsInput singleLine //this units the one line enter to true model={mentionsInputStyle} worth={worth} onChange={(e) => setValue(e.goal.worth)} > </div> );
A number of set off patterns
We are able to additionally resolve to make use of multiple set off sample as a substitute of the default @
set off sample. Fortunately, the react-mention
package deal helps this.
Let’s provoke a second set off sample. Import the useCallback
hook within the App.js
file. The useCallback
hook is used to cease the Point out
part from rerendering with out want:
import { useState, useCallback } from "react";
Subsequent, create an electronic mail validation regex. This can act as a further set off that detects if the enter is an electronic mail. It is going to then spotlight it as a point out.
operate App() { const [value, setValue] = useState(""); const emailRegex = /(([^[email protected]][email protected][^[email protected]]+.[^[email protected]]+))$/; ... return ( <div className="App"> <h2>Utilizing A number of set off patterns</h2> <MentionsInput model={mentionsInputStyle} worth={worth} onChange={(e) => setValue(e.goal.worth)} > <Point out model={mentionStyle} knowledge={customers} /> <Point out set off={emailRegex} knowledge={(search) => [{ id: search, display: search }]} onAdd={useCallback((...args) => { console.log(...args); }, [])} model={{ backgroundColor: "#d1c4e9" }} /> </MentionsInput> </div> );
Modifying the airing id
The react-mentions
library additionally permits us to alter the default displaying id
to our most well-liked one. We are able to obtain this through the use of the displayTransform
parameter.
<h2>Displaying ID</h2> <MentionsInput model={mentionsInputStyle} worth={worth} onChange={(e) => setValue(e.goal.worth)} > <Point out displayTransform={(id) => `<!--${id}-->`} model={mentionStyle} knowledge={customers} /> </MentionsInput>
Within the code block above, we return the id
from the consumer object and render it.
Scrollable textual content space
Textual content areas are responsive enter fields that regulate in top based mostly on a number of consumer inputs. This function may end up in a distorted UI and applies to our react-mentions
part. We’ll be making our textual content space scrollable to keep away from this distortion and create a nicer UI as a substitute.
First, we’ll import the merge
operate from the lodash
library into the App.js
file:
import merge from 'lodash/merge';
The merge
operate can be answerable for merging our mentionsInputStyle
with our new customized model.
operate App() { let customStyle = merge({}, mentionsInputStyle, { enter: { top: 80, overflow: "auto", }, highlighter: { top: 80, overflow: "hidden", boxSizing: "border-box", }, }); ... return ( <MentionsInput worth={worth} onChange={(e) => setValue(e.goal.worth)} model={customStyle} placeholder={"Point out folks utilizing '@'"} a11ySuggestionsListLabel={"Advised mentions"} > <Point out set off="@" knowledge={customers} model={mentionStyle} /> ); }
Within the code block above, we’re merging the mentionsInputStyle
to our newly up to date model. We’re additionally setting the peak and width of the textual content space to a set worth and routinely setting the overflow.
With that achieved, we may have a nicer UI with a scrollable part, as proven under:
Fetching responses from exterior sources
On this part, we’ll take a look at how we are able to use knowledge from an API in our kind. In lots of circumstances, our knowledge could also be coming from an exterior supply. Let’s see how we deal with our responses and add them to the react-mentions
knowledge property.
We’ll be working with and fetching customers from the JSON Placeholder API for this demo. Copy and paste the code block under into the App.js
file:
operate fetchUsers(question, callback) { if (!question) return; fetch(`https://jsonplaceholder.typicode.com/customers?q=${question}`, { json: true, }) .then((res) => res.json()) // Remodel the customers to what react-mentions expects .then((res) => res.map((consumer) => ({ show: consumer.username, id: consumer.identify })) ) .then(callback); }
Primarily based on the code block above, we’re making an API name to the jsonplaceholder
server. We handed two arguments into the fetch
operate: question
and callback
.
The question
argument holds the enter from the mentionInput
, whereas the callback
argument known as when we have now the response prepared.
Subsequent, we’re returning a listing of customers, looping by means of it, and returning the consumer’s identify and username as an object of show
and id
.
Lastly, we’re calling our operate within the knowledge property of the MentionsInput
part and displaying the id
:
<MentionsInput worth={worth} onChange={(e) => setValue(e.goal.worth)} model={mentionsInputStyle} placeholder="Point out any JsonPlaceholder username by typing `@` adopted by at the least one character" a11ySuggestionsListLabel={"Advised JsonPlaceholder username for point out"} > <Point out displayTransform={(id) => `@${id}`} set off="@" knowledge={fetchUsers} model={mentionStyle} /> </MentionsInput>
Fetching emojis
With the react-mentions
package deal, not solely can names be referenced and talked about, emojis might be talked about too!
Let’s check out learn how to fetch emojis from an exterior API and show them within the enter discipline after they’re searched.
operate App() { const [emojiValue, setEmojiValue] = useState([]); const notMatchingRegex = /($a)/; useEffect(() => { fetch( "https://gist.githubusercontent.com/oliveratgithub/0bf11a9aff0d6da7b46f1490f86a71eb/uncooked/d8e4b78cfe66862cf3809443c1dba017f37b61db/emojis.json" ) .then((knowledge) => { return knowledge.json(); }) .then((jsonData) => { setEmojiValue(jsonData.emojis); }); }, []); const queryEmojis = (question, callback) => { if (question.size === 0) return; const filterValue = emojiValue .filter((emoji) => { return emoji.identify.indexOf(question.toLowerCase()) > -1; }) .slice(0, 10); return filterValue.map(({ emoji }) => ({ id: emoji })); }; ... return ( <h3>Emoji assist</h3> <MentionsInput worth={worth} onChange={(e) => setValue(e.goal.worth)} model={mentionsInputStyle} placeholder={"Press '&' for emojis, point out folks utilizing '@'"} > <Point out set off="@" displayTransform={(username) => `@${username}`} markup="@__id__" knowledge={customers} regex={/@(S+)/} model={mentionStyle} appendSpaceOnAdd /> <Point out set off="&" markup="__id__" regex={notMatchingRegex} knowledge={queryEmojis} /> </MentionsInput> ); }
Primarily based on the code block above, we’re fetching and storing the emojis from our API in our emojiValue
as quickly because the web page masses. We do that utilizing the useEffect
hook and displaying the emojis every time the consumer searches particular key phrases.
Right here, we’re utilizing a double set off sample utilizing the &
image for emojis and the @
image for the customers array. The notMatchingRegex
serves as a filter for non-matching emojis.
Making a customized kind with @point out
performance
On this part, we can be placing collectively every little thing we’ve discovered in regards to the react-mentions
library to construct a remark kind.
First, create a CustomForm.jsx
file within the src
listing and paste within the code under:
// CustomForm.jsx import { useState } from 'react'; import { Point out, MentionsInput } from 'react-mentions'; import types from './FormInputStyle.module.css'; import mentionsInputStyle from './mentionsInputStyle'; import mentionStyle from './mentionStyle'; const CustomForm = () => { const [formState, setFormState] = useState({ username: '', remark: '', }); const [comments, setComments] = useState([]); const customers = [ { id: 'isaac', display: 'Isaac Newton', }, { id: 'sam', display: 'Sam Victor', }, { id: 'emma', display: '[email protected]', }, ]; const submit = () => { if (formState.username === '' || formState.remark === '') { alert('Please fill in all fields'); return; } setComments((feedback) => [ ...comments, { username: formState.username, comment: formState.comment, }, ]); setFormState({ username: '', remark: '', }); }; const present = new Date(); const date = `${present.getDate()}/${ present.getMonth() + 1 }/${present.getFullYear()}`;
Within the code above, we’re importing the package deal that we are going to be utilizing from react-mentions
in addition to the useState
hook for dealing with the feedback and state of the kinds.
The shape and remark state have additionally been set and are offering the dummy knowledge for the appliance. Our submit
operate checks if the fields are crammed and units the remark state. We now have a date
variable that will get the date of the remark.
Now, replace the return worth with the code under:
return ( <div className={types.kind}> <part className={types.formCard}> <h2 className={types.formTitle}>Remark Kind</h2> <enter sort="textual content" worth={formState.username} onChange={(e) => setFormState({ ...formState, username: e.goal.worth }) } placeholder="Enter Your Identify" /> <MentionsInput placeholder="Add Remark. Use '@' for point out" worth={formState.remark} onChange={(e) => setFormState({ ...formState, remark: e.goal.worth }) } model={mentionsInputStyle} > <Point out model={mentionStyle} knowledge={customers} /> </MentionsInput> <button onClick={submit}>Submit</button> </part> {feedback.size === 0 ? ( null ) : ( <part> {feedback.map((remark, i) => ( <div className={types.commentCard} key={i}> <p className={types.username}> {remark.username} on {date} </p> <h2>{remark.remark}</h2> </div> ))} </part> )} </div> ); }; export default CustomForm;
We’re passing the suitable props to the Point out
and MentionInput
elements and displaying the feedback under the shape (if there are any).
Nice! Subsequent, create a FormInputStyle.module.css
for styling and paste the next code into it:
* { margin: 0; padding: 0; box-sizing: border-box; } .kind { show: flex; flex-direction: column; align-items: middle; justify-content: middle; width: 100%; top: 100vh; background-color: #ffa5a5; } .formTitle { font-size: 2rem; coloration: crimson; margin-bottom: 1rem; } enter { top: 3rem; width: 25rem; margin-bottom: 1rem; padding: 1rem; font-size: 18px; border: 1px strong silver; } .formCard { width: 27rem; show: flex; flex-direction: column; background-color: rgb(54, 44, 24); padding: 1rem; } button { border: none; border-radius: 3px; coloration: white; background-color: inexperienced; font-size: 1.2rem; padding: 10px; margin-top: 1rem; } .commentCard { margin: 1.5rem; coloration: rgb(173, 173, 173); font-size: 1rem; background-color: #444; padding: 1rem; width: 27rem; } .username { coloration: white; font-size: 1.3rem; }
With that, we’re achieved creating the shape! You must see one thing like this:
Conclusion
On this article, we’ve discovered about react-mentions
, an easy-to-use library for constructing kinds with @point out
functionalities. We additionally regarded on the completely different functionalities of the react-mentions
package deal and the way we are able to use them. We additionally constructed a remark kind with @point out
performance utilizing the react-mention
package deal.
Thanks for studying!
Full visibility into manufacturing React apps
Debugging React functions might be troublesome, particularly when customers expertise points which can be arduous to breed. When you’re fascinated about monitoring and monitoring Redux state, routinely surfacing JavaScript errors, and monitoring sluggish community requests and part load time, strive LogRocket.
LogRocket is sort of a DVR for internet and cellular apps, recording actually every little thing that occurs in your React app. As an alternative of guessing why issues occur, you’ll be able to combination and report on what state your software was in when a difficulty occurred. LogRocket additionally screens your app’s efficiency, reporting with metrics like shopper CPU load, shopper reminiscence utilization, and extra.
The LogRocket Redux middleware package deal provides an additional layer of visibility into your consumer periods. LogRocket logs all actions and state out of your Redux shops.
Modernize the way you debug your React apps — begin monitoring without spending a dime.