DEV Community

Cover image for Let's create an Add Tags input with REACT JS
Shuvo
Shuvo

Posted on

Let's create an Add Tags input with REACT JS

In this article I will show you guys how you can create this multiple tags input using React.JS and a bit of CSS
React JS Add React JS Add Tags Input Tags Input Demo

Lets create a new react js project by running npx create-react-app myapp
Now to simplify things I am goin to delete all the files inside src folder except for App.js and index.js and create a style.css file. So our folder structure should look like this React app folder structure
Great now let's also delete all the unnecessary codes from index.js and App.js

// src/index.js
import React from 'react';
import ReactDOM from 'react-dom';
import "./style.css";
import App from './App';

ReactDOM.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>,
  document.getElementById('root')
);
Enter fullscreen mode Exit fullscreen mode
// src/App.js
function App() {
  return (
    <div className="App">
      <h2>Enter Some Tags ...</h2>
    </div>
  );
}

export default App;
Enter fullscreen mode Exit fullscreen mode

And I am also goin to add these CSS styles in our src/index.js

*{
    margin: 0;
    padding: 0;
}
html, body{
    height: 100%;
}
body{
    display: flex;
    justify-content: center;
    align-items: center;
    font-family: 'Courier New', Courier, monospace;
    font-weight: bold;
}

.tags-input-container{
    border: 2px solid #000;
    padding: .5em;
    border-radius: 3px;
    width: min(80vw, 600px);
    margin-top: 1em;
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: .5em;
}

.tag-item{
    background-color: rgb(218, 216, 216);
    display: inline-block;
    padding: .5em .75em;
    border-radius: 20px;
}
.tag-item .close{
    height: 20px;
    width: 20px;
    background-color: rgb(48, 48, 48);
    color: #fff;
    border-radius: 50%;
    display: inline-flex;
    justify-content: center;
    align-items: center;
    margin-left: .5em;
    font-size: 18px;
    cursor: pointer;
}

.tags-input{
    flex-grow: 1;
    padding: .5em 0;
    border: none;
    outline: none;
}
Enter fullscreen mode Exit fullscreen mode

If you want better explanation of the CSS you can watch this video of mine.

Okay now if we were to start our app by running npm start it should look like this
Basic react app
Alright now lets create a folder inside src folder named components inside that we are going to create a component file called TagsInput.js

// src/components/TagsInput.js
function TagsInput(){
    return (
        <div className="tags-input-container">
            <div className="tag-item">{/* One hardcoded tag for test */}
                <span className="text">hello</span>
                <span className="close">&times;</span>
            </div>
            <input type="text" className="tags-input" placeholder="Type somthing" />
        </div>
    )
}

export default TagsInput
Enter fullscreen mode Exit fullscreen mode

Now we can import and use in our App.js

// src/App.js
import TagsInput from "./components/TagsInput"

function App() {
  return (
    <div className="App">
      <h2>Enter Some Tags ...</h2>
      <TagsInput />
    </div>
  );
}

export default App;
Enter fullscreen mode Exit fullscreen mode

hard coded tag demo

Great, but no instead of having a hardcoded tag like this, we want an array and we should loop over the array and show a tag for each element. So lets use useState to do that

// src/components/TagsInput.js
import { useState } from 'react'

function TagsInput(){
    const [tags, setTags] = useState([
        "HTML", "CSS", "JavaScript"
    ])
    return (
        <div className="tags-input-container">
            { tags.map((tag, index) => (
                <div className="tag-item" key={index}>
                    <span className="text">{tag}</span>
                    <span className="close">&times;</span>
                </div>
            )) }
            <input type="text" className="tags-input" placeholder="Type somthing" />
        </div>
    )
}

export default TagsInput
Enter fullscreen mode Exit fullscreen mode

React dynamically rendered tags using useState and map
Okay now by default our array should be empty and when we type something in our input and press Enter a new item should be added in our tags state array. So lets create a function for that and add onKeyDown event listener to our input.

// src/components/TagsInput.js
import { useState } from 'react'

function TagsInput(){
    const [tags, setTags] = useState([])

    function handleKeyDown(e){
        // If user did not press enter key, return
        if(e.key !== 'Enter') return
        // Get the value of the input
        const value = e.target.value
        // If the value is empty, return
        if(!value.trim()) return
        // Add the value to the tags array
        setTags([...tags, value])
        // Clear the input
        e.target.value = ''
    }

    return (
        <div className="tags-input-container">
            { tags.map((tag, index) => (
                <div className="tag-item" key={index}>
                    <span className="text">{tag}</span>
                    <span className="close">&times;</span>
                </div>
            )) }
            <input onKeyDown={handleKeyDown} type="text" className="tags-input" placeholder="Type somthing" />
        </div>
    )
}

export default TagsInput
Enter fullscreen mode Exit fullscreen mode

event handling and updating state in React JS
And now finally when even user clicks on the
close(x) button of a tag the tag should be removed from our tags array. So lets create a function that take a index as its argument and removes the item at that index from our tags array. And add onClick listener to the close buttons.

// src/components/TagsInput.js
import { useState } from 'react'

function TagsInput(){
    const [tags, setTags] = useState([])

    function handleKeyDown(e){
        if(e.key !== 'Enter') return
        const value = e.target.value
        if(!value.trim()) return
        setTags([...tags, value])
        e.target.value = ''
    }

    function removeTag(index){
        setTags(tags.filter((el, i) => i !== index))
    }

    return (
        <div className="tags-input-container">
            { tags.map((tag, index) => (
                <div className="tag-item" key={index}>
                    <span className="text">{tag}</span>
                    <span className="close" onClick={() => removeTag(index)}>&times;</span>
                </div>
            )) }
            <input onKeyDown={handleKeyDown} type="text" className="tags-input" placeholder="Type somthing" />
        </div>
    )
}

export default TagsInput
Enter fullscreen mode Exit fullscreen mode

React JS Add Tags Input Finished Demo
And that's all we have successfully create a tags input using React and Bit of JavaScript.

Found it helpful? By me a Coffee ☕

Make sure you checkout my other articles and YouTube channel

0shuvo0 image

Was it helpful? Support me on Patreon

Patreon Logo

Discussion (3)

Collapse
suhakim profile image
sadiul hakim

Very nice

Collapse
0shuvo0 profile image
Shuvo Author

Thanks you 💓

Collapse
gauravsinhaweb profile image
Gaurav Sinha

Nice approach, do check my solution too: github.com/gauravsinhaweb/assignme...