[React] Tag Component 구현하기

fejigu·2022년 8월 29일
5

Toy Project

목록 보기
2/6



💻 Tag 구현 결과

✔️ 키보드의 Enter 키로 tags 배열에 새로운 태그를 추가하기
✔️ tags 배열에 새로운 태그를 추가되면 input 창 지우기
✔️ X 버튼 누르면 태그 삭제하기


⭐️⭐️⭐️ 다시 확인할 부분

🔎 cursor: pointer : cursor 속성은 요소 위에 마우스 커서가 올라갔을 때 보여줄 모양을 지정한다. ex) cursor:help,wait,crosshair,not-allowed,zoom-in,grab

🔎 filter() : filter() 메서드는 주어진 함수의 테스트를 통과하는 모든 요소를 모아 새로운 배열로 반환한다.

arr.filter(callback(element[, index[, array]])[, thisArg])

🔎onkeydown, onkeyup, onkeypress : 키를 눌렀을때, 키를 눌렀다가 땠을 때, 실제로 글자가 써질때 이벤트이다.


💻 Tag 코드

import { useState } from 'react';
import styled from 'styled-components';

export const TagsInput = styled.div`
  margin: 8rem auto;
  display: flex;
  align-items: flex-start;
  flex-wrap: wrap;
  min-height: 48px;
  width: 480px;
  padding: 0 8px;
  border: 1px solid rgb(1, 186, 138);
  border-radius: 6px;

  > ul {
    display: flex;
    flex-wrap: wrap;
    padding: 0;
    margin: 8px 0 0 0;

    > .tag {
      width: auto;
      height: 32px;
      display: flex;
      align-items: center;
      justify-content: center;
      color: rgb(1, 186, 138);
      padding: 0 8px;
      font-size: 14px;
      list-style: none;
      border-radius: 6px;
      margin: 0 8px 8px 0;
      background: rgb(242,243,244);
      border-radius: 15px;

      > .tag-close-icon {
        display: block;
        width: 16px;
        height: 16px;
        line-height: 16px;
        text-align: center;
        font-size: 14px;
        margin-left: 8px;
        color: rgb(1, 186, 138);
        border-radius: 50%;
        background: #fff;
        cursor: pointer;
      }
    }
  }

  > input {
    flex: 1;
    border: none;
    height: 46px;
    font-size: 14px;
    padding: 4px 0 0 0;
    :focus {
      outline: transparent;
    }
  }

  &:focus-within {
    border: 1px solid rgb(1, 186, 138);
  }
`;

export const Tag = () => {
  const initialTags = ['CodeStates', 'kimcoding'];

  const [tags, setTags] = useState(initialTags);
  const removeTags = (indexToRemove) => {
    // 태그를 삭제하는 메소드
    const filter = tags.filter((el,index) => index !== indexToRemove);
    setTags(filter);
  };

  const addTags = (event) => {
    // tags 배열에 새로운 태그를 추가하는 메소드 
    const inputVal = event.target.value;
    // 이미 입력되어 있는 태그인지 검사하여 이미 있는 태그라면 추가하지 말기 
    // 아무것도 입력하지 않은 채 Enter 키 입력시 메소드 실행하지 말기
    // 태그가 추가되면 input 창 비우기 
    if(event.key === "Enter" && inputVal !== '' && !tags.includes(inputVal)){
      setTags([...tags,inputVal]);
      event.target.value = '';
    }
  };

  return (
    <>
      <TagsInput>
        <ul id="tags">
          {tags.map((tag, index) => (
            <li key={index} className="tag">
              <span className="tag-title">{tag}</span>
              <span className="tag-close-icon" onClick={ () => removeTags(index)}>
                // tag-close-icon이 tag-title 오른쪽에 x로 표시, 삭제 아이콘을 click 했을 때 removeTags 메소드가 실행
              x</span>
            </li>
          ))}
        </ul>
        <input
          className="tag-input"
          type="text"
		//키보드의 Enter 키에 의해 addTags 메소드가 실행
          onKeyUp={(e) => {
            { addTags(e)
            }
          }}
          placeholder="Press enter to add tags_FEJIGU"
        />
      </TagsInput>
    </>
  );
};
profile
신규 서비스의 기획부터 개발, 운영까지 전 과정을 경험한 주니어 📱

0개의 댓글