All Articles

wecode 8주차_4일 TIL_프로젝트에 해시태그 추가기능을 넣어보자!

image.png

요즘 다들 정말 많이 하는 인스타그램! 나도 정말 많이 한다 먹을거 사진 올리는 재미가 쏠쏠~~ 인스타그램에서만 해시태그를 쓰는건 아니지만 가장 대표적인 예라서 썸네일은 인서타로 ㅋㅋㅋㅋ

팀원분이 2차 프로젝트에 태그 추가하는 기능을 넣어달라고 요청하셔서 열심히 구글링한 결과.. 찾아냈다!!! 그냥 하드코딩만 하면 실력이 늘지 않으니 분석하려고 포스팅해본다 ㅋㅋ (참고로 나는 styled-component를 사용했다.)

코드 먼저 봅시다.

state객체 내부에 선언

this.state = {tags: ["핵꿀잼", "리워드대박"]} 먼저 state 안에 tags라는 배열을 선언해주고, 그 안에 디폴트 태그값을 넣어준다!

태그 제거하는 기능

  removeTags = i => {
    const newTags = [...this.state.tags];
    newTags.splice(i, 1);
    this.setState({ tags: newTags });
  };

엔터로 추가, 백스페이스로 제거 기능

  inputKeyDown = e => {
    const val = e.target.value;
    if (e.key === "Enter" && val) {
      if (
        this.state.tags.find(tag => tag.toLowerCase() === val.toLowerCase())
      ) {
        return;
      }
      this.setState({ tags: [...this.state.tags, val] });
      this.tagInput.value = null;
    } else if (e.key === "Backspace" && !val) {
      this.removeTag(this.state.tags.length - 1);
    }
  };

엔터를 쳤을 때 값이 추가될 수 있도록 하는 기능인데.. 솔직히 LowerCase 부분은 왜 넣었는지 모르겠… 어서 지우고 테스트를 해봤다 룰루~

저걸 지우면 똑같은 문자를 대소문자 바꿔썼을때 추가가 되고, 저게 있어야 중복이 방지된다 ㅋㅋ 여튼 입력한 글자를 setState를 이용해 tags 배열에 추가를 하고.. 아래는 백스페이스 눌렀을 때 태그를 지우는 기능쓰~

리턴 전에 디스트럭처링을 먼저 해주고.. const { tags } = this.state;

태그 구조

<TagWrapper>
            <TagUL>
              {tags.map((tag, i) => (
                <TagLI key={tag}>
                  {tag}
                  <TagBtn
                    onClick={() => {
                      this.removeTags(i);
                    }}
                  >
                    +
                  </TagBtn>
                </TagLI>
              ))}
              <TagSpace>
                <TagInput
                  onKeyDown={this.inputKeyDown}
                  ref={c => {
                    this.tagInput = c;
                  }}
                />
              </TagSpace>
            </TagUL>
          </TagWrapper>

생긴건 간단하게 생겨가지고 꽤나 html 요소들이 필요하다 ㅋㅋㅋ TagInput이 태그를 입력하는 입력칸이고.. 그렇게 입력하면 <TagLI>버튼들이 생겨난다! css 속성도 함께 살펴보자.

const TagWrapper = styled.div`
  width: 363px;
  background: white;
  border-radius: 2px;
  display: flex;
  flex-wrap: wrap;
  padding: 5px 5px 0;
`;

const TagUL = styled.ul`
  display: inline-flex;
  flex-wrap: wrap;
  margin: 0;
  padding: 0;
  width: 100%;
`;

const TagLI = styled.li`
  align-items: center;
  background: linear-gradient(
    to right top,
    #233e6a,
    #44417c,
    #6c3f86,
    #953785,
    #bb2979
  );
  border-radius: 2px;
  color: white;
  display: flex;
  font-weight: 300;
  list-style: none;
  margin-bottom: 5px;
  margin-right: 5px;
  padding: 5px 10px;
`;

const TagBtn = styled.button`
  align-items: center;
  appearance: none;
  background: #333333;
  border: none;
  border-radius: 50%;
  color: white;
  cursor: pointer;
  display: inline-flex;
  font-size: 12px;
  height: 15px;
  justify-content: center;
  line-height: 0;
  margin-left: 8px;
  transform: rotate(45deg);
  width: 15px;
`;

const TagSpace = styled.li`
  background: none;
  flex-grow: 1;
  padding: 0;
`;

const TagInput = styled.input.attrs({
  type: "text",
  placeholder: "원하는 태그를 최대 5개까지 입력해주세요"
})`
  border: 1px solid #bdbdbd;
  border-radius: 4px;
  width: 100%;
  height: 43px;
`;

일단 다 써본 다음에 개발자도구를 열어서 바꾸고 싶은 속성값들은 바꿔주면 된다 ㅋㅋ 이렇게까지 하면 어떠한 결과물이 나오냐..!

image.png

이렇게 뙇!! 나는 우리 프로젝트의 로고 색깔에 맞춰 파+보로 bg color를 설정했는데 단색으로 해도 예쁠듯

사실 placeholder에 태그 5개 입력하라고 했는데.. 아직 제한 기능은 못 넣었다. 급한불부터 끄고 나중에 작업할 시간 있을때 해봐야지 ㅋㅋㅋㅋ

Reference