쉽게 생각하면 함수의 타입을 지정한다고 생각하면 된다
import { InputHTMLAttributes } from "react";
import styles from "./Input.module.css";
interface Props extends InputHTMLAttributes<HTMLInputElement> {}
export default function Input({ className = "", ...rest }: Props) {
const classNames = `${styles.input} ${className}`;
return <input className={classNames} {...rest} />;
}
위의 컴포넌트는 App.tsx에서 아래와 같이 쓰인다
<Input
id="password"
name="password"
type="password"
placeholder={t("password")}
value={values.password}
onChange={handleChange} /> --> App.tsx에서
아래의 코드와 같이 Input 컴포넌트를 선언하였다.
선언할때 HTMLAttributes와 같이 HTML형식의 타입으로 선언하였다
interface Props extends InputHTMLAttributes<HTMLInputElement> {}
->
- Attributes : 특정 태그의 속성들을 타입으로 만들어 놓음
- 제네릭의 타입 파라미터로(
<HTMLInputElement>)는 DOM 노드에 해당하는 타입을 적어줌- className 같은 것도 HTMLAttributes에 포함되어있으니 생략해도 좋음
이런식으로 HTML 태그에서 쓰는 기본 Prop을 가져올 수 있다- HTML 기본 속성으로 PropType을 지정하고 싶을때HTMLAttributes로 끝나는 타입을 써서제네릭 안에는(<>)
- HTML DOM 노드에 해당하는 타입을 넣은 다음 해당 타입을 상속(extends)해서 사용가능
import { ReactNode } from "react";
import styles from "./Button.module.css";
interface Props {
className?: string;
id?: string;
children?: ReactNode;
onClick: any;
}
export default function Button({ className = "", ...rest }: Props) {
const classNames = `${styles.button} ${className}`;
return <button className={classNames} {...rest} />;
}
props에 대한 타입을 설정할것이다.
// props는 객체니 인터페이스를 써서 지정할거다
interface Props {
className?: string;
id?: string;
children?: ReactNode;
onClick: any;
//이벤트 헨들러에 대한 타입은 나중에 알아볼거기 때문에 일단 any로 둠
children?: ReactNode; 에 대해서
1. 리엑트에서는 children 타입이 ReactNode로 대부분 정해져 있음
2. 만약 children이 없는 경우도 처리하고 싶으면 children옆에 ? 를 써서 Optional로 만들기
export default function Button({ className = "", ...rest }: Props) {
const classNames = `${styles.button} ${className}`;
return <button className={classNames} {...rest} />;
}
// 아래 코드와 동일함
const Button = ({ className = "", ...rest }: Props) => {
const classNames = `${styles.button} ${className}`;
return <button className={classNames} {...rest} />;
};
아래의 코드를 Props 타입을 지정하되, level이라는 Prop의 타입은 'info' | 'warn'이고, 필수적이지 않는다. 하지만 children은 필수적으로 받도록 코드짜보기.
import Alert from './Alert';
function App() {
return (
<div>
<Alert level="info">
안내 메시지 예시입니다.
</Alert>
<Alert level="warn">
경고 메시지 예시입니다.
</Alert>
</div>
);
}
export default App;
import { ReactNode } from 'react';
import styles from './Alert.module.css';
interface Props {
level?: 'info' | 'warn';
children: ReactNode;
}
export default function Alert({ level = 'info', children }: Props) {
return (
<div className={`${styles.alert} ${styles[level]}`}>
{children}
</div>
);
}
Props는 함수의 파라미터이니까, 함수의 파라미터 타입을 정의하듯이 정의하면 된다. 보통은 interface로 정의한다. level Prop은 필수가 아니기 때문에 ?를 사용해서 옵셔널 프로퍼티로 만들어 줬다. children이라는 Prop은 필수이기 때문에 ?를 사용하지 않고 만들어 주었다. children은 자식 컴포넌트들을 받는 Prop인데요. 보통은 ReactNode라는 타입을 사용하면 된다.