react의 타입은 React.FC
이다.
const App:React.FC = ()=>{
return (
<div>
(생략)
</div>
)
}
일단 타입 생성하고
// (/model/restaurant.ts)
export type Restaurant = {
name : string;
category : string;
address : {
city : string;
detail : string;
zipCode : number;
};
menu : {
name : string;
price : number;
category : string;
}[]
}
사용하는 방법은
//(App.tsx)
import {Restaurant} from './model/retaurant'
let data:Restaurant = { 포맷에 맞는 데이터 }
const App:React.FC = ()=>{
return (
<div>
<Location info={data}/>
</div>
)
}
특정 type의 데이터를 하위 컴포넌트의 props로 넘겨줄 땐,
//(Location.tsx)
import {Restaurant} from './model/retaurant'
interface OwnProps {
info : Restaurant
}
const Location:React.FC<OwnProps> = (props)=>{
return(
<div>Location</div>
)
}
export default Location
위에서 정의한 Restaurant
타입을 아래와 같이 만들 수도 있다.
// (/model/restaurant.ts)
export type Restaurant = {
name : string;
category : string;
address : Address;
menu : Menu[];
}
export type Address = {
city : string;
detail : string;
zipCode : number;
}
export type Menu = {
name : string;
price : number;
category : string;
}
useState를 통해 특정 타입의 상태를 만드려면
//(App.tsx)
import {useState) from 'react'
import {Restaurant, Address} from './model/retaurant'
let data:Restaurant = { 포맷에 맞는 데이터 }
const App:React.FC = ()=>{
const [myRestaurant, setMyRestaurant] = useState<Restaurant>(data)
return (
<div>
(생략)
</div>
)
}
<Location>
컴포넌트에 변수와 함수 타입을 설정해서 전달해야 한다.
//(App.tsx)
import {useState) from 'react'
import {Restaurant, Address} from './model/retaurant'
let data:Restaurant = { 포맷에 맞는 데이터 }
const App:React.FC = ()=>{
const [myRestaurant, setMyRestaurant] = useState<Restaurant>(data)
const changeAddress = (address:Address)=>{
setMyRestaurant({...myRestaurant, adress:adress})
return (
<div>
<Location info={data} changeAddress={changeAddress}/>
</div>
)
}
props
의 타입을 직접 정의해야 하는 부분이 중요하다.
//(Location.tsx)
import {Restaurant} from './model/retaurant'
interface OwnProps {
info : Restaurant,
changeAddress(address:Address):void
}
const Location:React.FC<OwnProps> = (props)=>{
return(
<div>Location</div>
)
}
export default Location
이미 정의된 type를 참조해서 새로운 타입을 만들 때 쓴다.
//(./BestMenu.tsx)
...
interface OwnProps extends Menu{
showBestMenu(name:string):string
}
const BestMenu:React:FC<OwnProps> = ({name, price, category, showBestMenu}) => {
return(
<div>BestMenu</div>
)
}
export default BestMenu
//(App.tsx)
...
const App:React.FC = ()=>{
const showBestMenu = (name:string)=>{
return name
}
return (
<div>
<BestMenu name="맛있는 음식" showBestMenu={showBestMenu}/>
</div>
)
}
위에서는 interface
로 props의 type을 extends
했다.
type
으로도 extends
와 같은 기능을 구현할 수 있다.
아래와 같이 &
를 활용하면 된다.
//(./BestMenu.tsx)
...
type OwnProps = Menu & {
showBestMenu(name:string):string
}
...
앞서 정의한 type 중, Address
의 zipCode
를 뺀 type을 만들고 싶다면
// (/model/restaurant.ts)
...
export type Address = {
city : string;
detail : string;
zipCode : number;
}
export type AddressWithoutZipCode = Omit<Address, 'zipCode'>
아래와 같이 extends
와 결합하여 사용할 수도 있다.
price
에 대한 정보를 props
에서 받지 않으려면 아래와 같이 Omit
을 쓰면 된다.
//(./BestMenu.tsx)
...
interface OwnProps extends Omit<Menu,'price'>{
showBestMenu(name:string):string
}
const BestMenu:React:FC<OwnProps> = ({name, category, showBestMenu}) => {
return(
<div>BestMenu</div>
)
}
export default BestMenu
API의 응답 데이터가 Restaurant
, Menu
와 같을 땐,
아래와 같이 여러 타입에 대해 대응할 수 있다.
export type ApiResponse<T> = {
data:T[],
totalPage:number,
page:number
}
export type RestaurantRespone = ApiResponse<Restaurant>
export type MenuRespone = ApiResponse<Menu>
React.FC가 예전에는 많이 썼던 것 같은데 최근에는 사용하지 않는 추세인 것 같아요. CRA도 기본 타입에서 제거했던 것 같고, 저는 요즘 props타입만 지정해서 사용하는 형태를 선호하고 있어요