1. useState 상태 변경 함수의 타입 정의
isFormOpen, setIsFormOpen 을 props 를 이용해 다른 컴포넌트로 보내어 사용해야 하는 상황에서는 props 의 타입을 정해줘야 한다.
const [isFormOpen, setIsFormOpen] = useState(false);
import React, { FC } from 'react'
import { FiPlusCircle } from 'react-icons/fi'
type TFormProps = {
isFormOpen: boolean,
setIsFormOpen:
React.Dispatch<React.SetStateAction<boolean>>
}
const SideForm: FC<TFormProps> = ({isFormOpen, setIsFormOpen}) => {
return (
<div>
// ...
<FiPlusCircle onClick={() => {
setIsFormOpen(!isFormOpen);
}}/>
</div>
)
}
export default SideForm
궁금증1. React.Dispatch<React.SetStateAction<A>> 뭐하는 애지?
상태변경 함수를 정의하는 타입으로 A 에 상태변경 함수에 들어가는 인자값의 타입을 적어주면 된다.
타입이 복잡해 보이니 뜯어보면 이렇다.
- 상태 변경 함수 자체 타입: React.Dispatch<A>
- 상태 변경 함수 인자 타입: React.SetState<A>
여기서 궁금증2..
궁금증2. 상태 변경 함수의 인자에 왜 또 인자 타입을 정의하는거지?
상태 변경 함수는 두 가지 사용 방식이 있다. SetStateAction 은 useState 가 받을 수 있는 인자의 타입을 지정해줘야 하기 때문에 아래의 두 가지 방식을 모두 지정하기 위해 인자가 있는 것이라고 생각하면 된다.
// 인자를 넣어주는 방식
setCount(3);
// 함수를 인자로 넣어주는 방식 (이전 값 참조할 때 사용)
setCount((prev) => prevCount + 1);
2. clsx 라이브러리
리액트에서 조건부로 className 을 적용하고 싶을 때 편하게 사용할 수 있는 라이브러리이다.
기본적으로 이렇게 사용할 수 있다.
clsx(
'button', // 기본 클래스
true && 'button-red', // 조건부 클래스
false && 'button-blue' // 조건부 클래스
)
아래의 경우는 객체를 clsx 에 객체를 사용한 경우인데, 객체의 키는 클래스명이고 객체의 값은 조건이다. 만약 값이 true 라면 해당 클래스가 적용되고 false 라면 해당 클래스는 적용되지 않는다.
{boardArray.map((board,index) =>
<div key={board.boardId}
onClick={() => setActiveBoardId(boardArray[index].boardId)}
className={
clsx(
{
[boardItemActive]:
boardArray.findIndex(b => b.boardId === activeBoardId) === index,
},
{
[boardItem]:
boardArray.findIndex(b => b.boardId === activeBoardId) !== index
}
)
}
>
<div >
{board.boardName}
</div>
</div>
)}
// ...
- 더 많은 사용법 리드미 참고
GitHub - lukeed/clsx: A tiny (239B) utility for constructing `className` strings conditionally.
A tiny (239B) utility for constructing `className` strings conditionally. - lukeed/clsx
github.com
3. 이벤트 객체의 타입은 ChangeEvent
ChangeEvent 는 HTMLInputElement, HTMLSelectElement, HTMLTextAreaElement 등 다양한 HTML 요소와 함께 사용할 수 있다.
// Input 요소의 경우
const handleInputChange = (e: ChangeEvent<HTMLInputElement>) => {
setInputValue(e.target.value);
}
// TextArea 요소의 경우
const handleTextChange = ((e: ChangeEvent<HTMLTextAreaElement>) => {
setText(e.target.value);
})
4. Onblur Onclick OnMouseDown

글을 쓰고 체크 표시를 누르면 폼이 닫히면서 게시판이 등록되고 다른 곳을 누르면 폼이 닫히는 기능을 구현했는데, 체크 표시를 눌러도 닫히지 않는 문제가 생겼다.
- 문제의 원인
폼 외에 다른 곳을 눌렀을 때 폼이 닫히는 기능 -> onBlur 이라는 이벤트로 구현
체크 표시를 눌렀을 때 폼이 닫히는 기능 -> onClick 으로 구현
-> onClick 이벤트보다 onBlur 이벤트가 먼저 발생하기 때문에 onBlur 이 우선 실행되어 click 이벤트가 무시됨.
- 문제 해결
onMouseDown 이벤트를 사용해서 해결할 수 있다.
onClick 이벤트는 마우스로 눌렀다가 뗄 때 발생하고 onMouseDown 이벤트는 마우스가 눌릴 때 발생하기 때문에 onMouseDown 이벤트가 발생한 시점에서 blur 이벤트가 발생하더라고 onMouseDown 이벤트가 먼저 실행되기 때문에 클릭이 제대로 처리됨!
5. React.FC<T> vs FC<T>
그냥 React 를 import 했냐 안했냐의 차이
React 를 미리 import 했다면 조금 더 간결하게 쓸 수 있다.
import React, { FC } from 'react'; // React 를 먼저 import 했기 때문에 FC 로 쓸 수 있음
const MyComponent: FC<Props> = ({ prop1, prop2 }) => {
return <div>{prop1}</div>;
};
// React 를 import 하지 않았기 때문에 React.FC 로 써줘야 함
const MyComponent: React.FC<Props> = ({ prop1, prop2 }) => {
return <div>{prop1}</div>;
};
'TIL with Programmers' 카테고리의 다른 글
[TIL] 11/7 프론트엔드 심화4 - React Beautiful Dnd, firebase 로그인 구현, 배포하기 (0) | 2024.11.07 |
---|---|
[TIL] 11/6 프론트엔드 심화3 - 모르는 것 정리 (0) | 2024.11.06 |
[TIL] 11/4 프론트엔드 심화1 - 모르는거 정리 (0) | 2024.11.04 |
[TIL] 11/1 props, 모달창 만들기 (0) | 2024.11.01 |
[TIL] 10/31 클래스/함수형 컴포넌트, useState (0) | 2024.10.31 |