태그 달기

Donggu(oo)·2023년 1월 22일
0

React 기능 구현

목록 보기
7/14
post-thumbnail

1. 알아야 할 내용


  • 아래의 () => removeTags(index) 부분에서 removeTags 함수를 전달할 때 index를 인자로 받고 있다. removeTags(index)로 전달하게 되면 JSX 문법에 따라 함수의 형태로 이벤트 핸들러를 전달해야 되는 규칙에 어긋나 undefined를 전달하는 것과 같게 되어 Error가 발생한다. 따라서 화살표 함수로 감싸서 함수의 형태로 전달해주어야 한다.
<span className="tag-close-icon" onClick={() => removeTags(index)}>X</span>

2. 전체 코드


  • 태그 구현 코드
export const Tag = () => {
  const [tags, setTags] = useState([]);

  // 태그 추가
  const addTags = (event) => {
    // Enter키 입력 시 이미 추가된 태그는 추가하지 않음, input창이 비어있으면 태그 추가하지 않음
    if (event.key === 'Enter' && !tags.includes(event.target.value) && event.target.value !== '') {
      setTags([...tags, event.target.value]);  // 기존에 추가된 태그 뒤에 새로운 태그 추가
      event.target.value = '';  // 태그 추가 후 input 창 비우기
      console.log(event.key)
    }
  };

  // 태그 삭제
  const removeTags = (deleteIndex) => {
    // removeTags 함수의 버튼에서 클릭한(선택한) tag의 index값과 다른 tag들만 새로운 배열로 처리해서 state 값을 변경한다.
    setTags(tags.filter((value) => value !== tags[deleteIndex]));
  };

  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)}>X</span>
            </li>
          ))}
        </ul>
        <input
          className="tag-input"
          type="text"
          onKeyUp={(event) => addTags(event)}
          placeholder="Press enter to add tags"
        />
      </TagsInput>
    </>
  );
};
  • CSS
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(214, 216, 218);
  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: #fff;
      padding: 0 8px;
      font-size: 14px;
      list-style: none;
      border-radius: 6px;
      margin: 0 8px 8px 0;
      background: #4000c7;
      > .tag-close-icon {
        display: block;
        width: 16px;
        height: 16px;
        line-height: 16px;
        text-align: center;
        font-size: 14px;
        margin-left: 8px;
        color: #4000c7;
        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 #4000c7;
  }
`;

0개의 댓글