일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
- til
- Protocol
- url
- SQL
- http
- github
- W
- Fetch
- firestoredatabase
- HTML
- API
- CSS
- web
- nosql
- IntersectionObserver
- bootstrap
- JavaScript
- useEffect
- this
- data
- db
- jQuery
- 배포
- Github Pages
- Database
- REACT
- TMDB
- Boostrap
- supabase
- Cloud
- Today
- Total
072DATA
해시태그 기능 구현하기 본문
해시 태그 기능을 구현하는 방법을 차례대로 적어 보겠음
상태 선언 및 타입 지정
먼저 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 요청 해주면 끝!