오늘도 코딩하나

[React] TypeScript로 component 설계하기 본문

React/노마드코더

[React] TypeScript로 component 설계하기

오늘도 코딩하나 2025. 1. 16. 02:07
강의 내용 : 강의 링크
#3.0 ~ #3.7

 

 Interface

    interface : object shape을 TypeScript에게 설명해준다.

 

   * Prop Types는 prop이 거기에 있는지 없는지 확인해주지만, 코드를 실행한 "후"에만 확인 가능하다.

   * 하지만 우리는 TypeScript처럼 코드 실행 "전"에 확인 하고싶다!!

   * 그래서 우리는 Prop Types를 사용하지 않고, prop들을 Typescript로 보호해줄거다!

     ⇒ Interface

 

- Circle.tsx

import { styled } from "styled-components";

interface ContainerProps {
  bgColor: string;
}

const Container = styled.div<ContainerProps>`
  width: 200px;
  height: 200px;
  background-color: ${(props) => props.bgColor};
  border-radius: 100px;
`;

interface CircleProps {
  bgColor: string;
}

function Circle({ bgColor }: CircleProps) {
  return <Container bgColor={bgColor} />;
}

export default Circle;
  • Circle 컴포넌트가 받는 prop : CircleProps.bgColor
    Circle 컴포넌트에 전달된 bgColor를 Container 컴포넌트로 전달하는 역할
  • Container 컴포넌트가 받는 prop : ContainerProps.bgColor
    bgColor를 받아서 스타일링에 사용
  • Circle 컴포넌트와 Container 컴포넌트가 받을 prop가 다른 경우, 각 컴포넌트에서 별도의 interface를 사용
    그러나, 동일한 경우에는 하나의 interface만 사용

- App.tsx

import Circle from "./Circle";

function App() {
  return (
    <div>
      <Circle bgColor="teal" />
      <Circle bgColor="tomato" />
    </div>
  );
}

export default App;

Default props vs Optional props

interface ContainerProps {
  bgColor: string;
  borderColor: string;
}

const Container = styled.div<ContainerProps>`
  width: 200px;
  height: 200px;
  background-color: ${(props) => props.bgColor};
  border-radius: 100px;
  border: 1px solid ${(props) => props.borderColor};
`;

interface CircleProps {
  bgColor: string;
  borderColor?: string;
  text?: string;
}

function Circle({ bgColor, borderColor, text = "default text" }: CircleProps) {
  return (
    <Container bgColor={bgColor} borderColor={borderColor ?? "white"}>
      {text}
    </Container>
  );
}
  • borderColor?
    - optional props로, 전달하지 않아도 Circle 컴포넌트가 정상적으로 작동할 수 있다.
    - borderColor porp을 전달하지 않으면 undefined로 처리된다.
  • borderColor={borderColor ?? "white"}
    - default props로 borderColor가 null 또는 undefined일 경우 기본값 "white"를 할당한다.

TypeScript와 React state

const [value, setValue] = useState(0);
setValue("hello");

   - setValue("hello")에서 아래와 같은 오류 발생

TS2345: Argument of type 'string' is not assignable to parameter of type 'SetStateAction<number>'.
  • TypeScript는 state 초기값을 가지고 자동으로 타입 추론한다.
  • useState(0) → 초기값이 0이므로 value:number

 

   * 만약 number, string 타입을 모두 받고 싶다면?

const [value, setValue] = useState<number | string>(0);

Typescript를 이용해서 form에 타입 적용하기

function App() {
  const [value, setValue] = useState("");
  const onChange = (event: React.FormEvent<HTMLInputElement>) => {
    const {
      currentTarget: { value },
    } = event;
    setValue(value);
  };
  const onSubmit = (event: React.FormEvent<HTMLFormElement>) => {
    event.preventDefault();
    console.log("hello", value);
  };
  return (
    <div>
      <form onSubmit={onSubmit}>
        <input
          value={value}
          onChange={onChange}
          type="text"
          placeholder="username"
        />
        <button>Log in</button>
      </form>
    </div>
  );
}
  • event: React.FormEvent<HTMLInputElement>
    : event는 React.FormEvent 타입으로 정의되며, HTMLInputElement 요소에 대한 이벤트
  • React.FormEvent : React에서 제공하는 form관련 이벤트 타입
  • HTMLInputElement : <input> 요소에 특화된 타입
  • typescript에서는 event.target이 아닌 event.currentTarget

✅ 참고 url

1. JavaScript 라이브러리에 대한 TypeScript 타입 정의를 제공하는 오픈소스

https://github.com/DefinitelyTyped/DefinitelyTyped

 

GitHub - DefinitelyTyped/DefinitelyTyped: The repository for high quality TypeScript type definitions.

The repository for high quality TypeScript type definitions. - DefinitelyTyped/DefinitelyTyped

github.com

npm i --save-dev @types/styled-components

 

2. React의 이벤트 처리 방식

https://legacy.reactjs.org/docs/events.html

 

SyntheticEvent – React

A JavaScript library for building user interfaces

legacy.reactjs.org