[포스코x코딩온] 웹개발자 풀스택 과정 4차 팀프로젝트 - 타입스크립트

 

이번 프로젝트에서 타입스크립트를 사용하며 겪은 배운점과 고쳐야 될 점을 나열한 블로그다. 앞으로 어떻게 사용할 지에 대한 간단한 정리 형식으로 써놓았다.

 

1. 타입스크립트 사용 한 곳.

1-1. API 호출시 타입 선언

1-2. 부모에서 자식 컴포넌트로 Props 전달시 타입 선언

1-3. useState, useRef 등 ReactHook 사용시 타입 선언


 

1-1. API 호출시 타입 선언

✂️ 수정 전

// API 타입 선언
const [resentProductList, setResentProductList] = useState<ApiResponse[]>([]);
    
// API 호출
useEffect(() => {
        const getResentProduct = async () => {
            try {
                const res = await axios.get<ApiResponse, any>(
                    `${process.env.REACT_APP_API_KEY}/shop/best`,
                );
                setResentProductList(res.data);
            } catch (error) {
                console.error('데이터를 가져오는 중 오류 발생:', error);
            }
        };
        getResentProduct();
    }, []);

 

급하게 개발을 하다보니 타입 지정을 제대로 안해줬다. (ChatGPT의 힘을 빌려 씀..)

any 타입을 사용할거면 타입을 지정해줄 필요가 없다는 말이 있을 만큼 최대한 지양해야 한다. 프로젝트가 끝나고 다시보니 구지 any 타입을 지정 안해줘도 될거 같아 리팩토링을 해봤다.

 

 

✂️ 수정 후

 useEffect(() => {
        const getResentProduct = async () => {
            try {
                const res = await axios.get<ApiResponse[]>(
                    `${process.env.REACT_APP_API_KEY}/shop/new`,
                );
                setResentProductList(res.data);
            } catch (error) {
                console.error('데이터를 가져오는 중 오류 발생:', error);
            }
        };
        getResentProduct();
    }, []);

 

지금 고쳐보니 어이없는 실수였다. data가 배열 형태로 오니 타입 호출을 배열로 해주면 간단하게 해결할 수 있는 코드였다.

 

 

1-2. 부모에서 자식 컴포넌트로 Props 전달시 타입 선언

나는 이번 프로젝트에서 두가지의 경우로 props를 전달했다. 컴포넌트끼리 props를 전달하는 방법과 styled-component로 props를 전달하는 방법을 사용했다. 

 

1️⃣ 컴포넌트끼리 props전달하는 방법

<RoomReviewWrite address={address} mylat={mylat} mylng={mylng}/>

 

총 3개의 변수를 자식 컴포넌트로 전달하려 한다. 

// 타입 선언
interface Props {
    address: string;
    mylat: number;
    mylng: number;
}

// 자식 컴포넌트
const RoomReviewWrite: React.FC<Props> = ({ address, mylat, mylng }) => {
    return <>
    	...
    	</>
    }

 

타입 선언 후 컴포넌트에 타입을 선언해주면 된다. 

 

 

2️⃣ styled-component로 props를 전달하는 방법

 

나는 버튼이 호버되었을 때 opacity를 0.5로 바꾸는 동작을 하려한다. (버튼이 호버되었을 때 동작하는 함수는 다른 컴포넌트에 있다. zustand를 사용해서 전역 상태로 관리를 하고 이 값을 props로 받은 것이다.)

 

// 타입 지정
interface CssProps {
    isButtonHovered: boolean;
}

// 글쓰는 컴포넌트 활성화 상태
    const { isButtonHovered, setIsButtonHovered } = useButtonHoverd();
    
// 적용할 컴포넌트
<_reviewComponent isButtonHovered={isButtonHovered}>
    
    
// styled-component
const _reviewComponent = styled.div<CssProps>`
    background-color: white;
    width: 20%;
    ${(props) => props.isButtonHovered && `opacity: 0.5;`}
`;

 

 

1-3. useState, useRef 등 ReactHook 사용시 타입 선언

1️⃣ useState 사용

const [openPostModal, setOpenPostModal] = useState(false);

 

기본적으로 타입을 지정해 줘도 되는데, 기본값을 넣으면 알아서 타입스크립트가 타입을 추론하기 때문에 따로 지정을 안해줘도 된다.

 

2️⃣useRef 사용

 // 타입 선언
 const categoryDiv = useRef<HTMLDivElement>(null);


<_categoryDiv
    ref={categoryDiv}
>

 

그냥 해당 DOM 요소를 취득하는 방법이다. 이때 DOM 취득시 null이 되는 이유는 최초 렌더링 시, return 부분이 실행되지 않아서, 실제 DOM에 반영되지 않았는데 참조하려는 이유 때문이다.

 

그래서 아래와 같이 항상 존재 여부를 검사하고 사용해야 한다.

// 실제 DOM에 반영된 이후, DOM취득 가능
  useEffect(() => {
    // ref는 항상 존재여부를 검사하고 사용해야 한다(단축평가 Good!)
    categoryDiv.current && inputRef.current.focus();
  });