072DATA

해시태그 기능 구현하기 본문

카테고리 없음

해시태그 기능 구현하기

0720 2024. 10. 15. 02:48

 

해시 태그 기능을 구현하는 방법을 차례대로 적어 보겠음

 

 

상태 선언 및 타입 지정

 

먼저 2가지 상태(useState)가 필요한데 category를 입력하는 Input창에 대한 상태(useState) categoryInput 와

실제로 데이터를 보낼 때 담아야할 상태(useState) 는 formData로 선언했음

  const [categoryInput, setCategoryInput] = useState<string>("");
  const [formData, setFormData] = useState<Omit<WriteTypes, "fileInputRef">>({
      post_category: [],
  }

 

 formData의 타입 지정은 따로 interface로 만들어서 지정했고 

문자열 요소들로 구성된 배열 타입으로 지정했음

export interface WriteTypes {
// 다른 타입 생략
  post_category: string[];
}

 

 

.tsx

 <div className="flex flex-col">
      <span>태그</span>
      <div className="flex flex-row gap-2">
        <div className="flex flex-wrap gap-2">
          {formData.post_category.map((tag, index) => (
            <div key={index} className="flex items-center space-x-1 bg-gray-200 gap-2 p-1 rounded">
              <span>{tag}</span>
              <button type="button" onClick={() => handleRemoveTag(index)}>
                x
              </button>
            </div>
          ))}
        </div>
        <input
          placeholder="태그 입력 후 엔터"
          className="border w-[140px] text-center"
          name="post_category"
          value={categoryInput}
          onChange={(e) => setCategoryInput(e.target.value)}
          onKeyDown={handleCategoryAdd}
        />
      </div>
    </div>

 

formData의 post_category 배열을 map을 사용해서 태그를 뿌려주고

이 태그들에 삭제 버튼을 만들어서 설정된 해시태그를 삭제할 수 있도록 하였음

 

태그 삭제

const handleRemoveTag = (index: number) => {
    setFormData((prev) => ({
      ...prev,
      post_category: prev.post_category.filter((_, i) => i !== index)
    }));
};

 

아주 간단하게 index를 인자로 받은 값과

category 배열 속 index가 일치하지 않는 것들만 다시 배열에 담아줌

이러면 상태가 변경되어 선택된 태그를 제외한 뒤 리렌더링 일어남

 

 

태그 추가

다시 tsx 문법으로 돌아가서 input 창을 보면  onChange 함수에 setState를 사용하여 

categoryInput의 값을 사용자가 입력한 값으로 변경시키고

 

onKeyDown은 React에서 사용되는 이벤트 핸들러 중 하나로

이 속성을 사용하여 사용자가  특정 키를 눌렀을 때 태그가 추가 되도록 함수를 만들면 됨

 

  const handleCategoryAdd = (e: React.KeyboardEvent<HTMLInputElement>) => {
    if (e.key === "Enter") {
      e.preventDefault();
      if (categoryInput.length === 0 || categoryInput.trim() === "") {
        setCategoryInput("");
        return alert("빈 태그는 입력할 수 없습니다.");
      }
      setFormData((prev) => ({
        ...prev,
        post_category: [...prev.post_category, categoryInput.trim()]
      }));
      setCategoryInput("");
    }
  };

 

먼저 인자 값으로 이벤트를 받아온 다음 타입 지정을 해줌 매개변수의 타입은

e: React.KeyboardEvent<HTMLInputElement>로 키보드 이벤트를 나타내는 타입임

 

그 다음 사용자가 Enter키를 누르면 e.preventDefault()를 사용하여

Enter 키를 눌렀을 때 폼이 제출되는 기본 동작을 막음

 

빈 문자열을 입력하거나 아무것도 입력하지 않았을 때 유효성 검사를 거치고

 

정상적으로 태그를 입력했을 때 setState를 사용하여 스프레드 문법으로

기존의 폼 데이터를 가져오고 post_category 배열에 현재 입력된 categoryInput을 추가함

이때 trim() 메서드를 사용하여 공백을 제거한 값을 추가

 

결과

 

결과처럼 태그가 잘 들어오고 삭제되는 것까지 완료됨

이렇게 컴포넌트를 분리해서 태그 기능을 만들고 데이터베이스에 저장할 때

API요청 함수를 사용하여 formData를 POST 요청 해주면 끝!