Let's create an Add Tags input with REACT JS
Tags: react, javascript, webdev, tutorial
Published: 2022-01-17 03:57:25

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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/p76m0n8p91ilzzy1c0tz.png)

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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qefxn9j19xo0j39wtr9o.png)
Great now let's also delete all the unnecessary codes from `index.js` and `App.js`
```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')
);
```
```js
// src/App.js
function App() {
  return (
    <div className="App">
      <h2>Enter Some Tags ...</h2>
    </div>
  );
}

export default App;
```
And I am also goin to add these CSS styles in our **src/index.js**
```css
*{
    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;
}
```
If you want better explanation of the CSS you can watch this video of mine. {% youtube l8Jd7Ub4yJE %}

Okay now if we were to start our app by running `npm start` it should look like this
![Basic react app](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7thkpse0j5zpg9cnwqrn.png)
Alright now lets create a folder inside **src** folder named **components** inside that we are going to create a component file called **TagsInput.js**
```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
```
Now we can import and use in our `App.js`
```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;
```
![hard coded tag demo](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/koo8azqt6x7jocwn3arq.png)
 
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
```js
// 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
```
![React dynamically rendered tags using useState and map](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/008ififz0bat53doxs3c.png)
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.
```js
// 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
```
![event handling and updating state in React JS](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/v9258fkuytm7s6duzcws.png)
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.
```js
// 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
```
![React JS Add Tags Input Finished Demo](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4esttzf3f09i6oys3awb.png)
And that's all we have successfully create a tags input using React and Bit of JavaScript.

Found it helpful? [By me a Coffee ☕](https://www.buymeacoffee.com/0shuvo0)

Make sure you checkout my other articles and YouTube channel
{% user 0shuvo0 %}
## Was it helpful? Support me on Patreon
[![Patreon Logo](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7vnw8g7vs5pok3jwgtgv.png)](https://www.patreon.com/0shuvo0)