행복을 담는 블로그
[React + TS] React에서 Typescript 사용하는 방법 알아보기 (2) 본문
5. Passing Props
예시 1) props로 {count}를 넘겨줄 때, type을 함께 지정해준다.{count} : {count : string}
import { useState } from "react";
function Parent() {
const [count, setCount] = useState("");
return <Child count={count}></Child>;
}
function Child({ count }: {count: string) {
return <div>{count}</div>;
}
export default Parent;
예시 2)
import { useState } from "react";
function Parent(){...}
type Props = {
count: string;
};
function Child({ count }: Props) {
return <div>{count}</div>;
}
export default Parent;
▶️ type을 위로 분리하여 선언하고, 선언한 타입을 컴포넌트에서 props으로 받을 수 있다.
props로 값을 넘겨주는 경우, 어떤 타입인지 알 수 없을 때,
: 마우스 hover 하면 어떤 타입의 값인지 확인 할 수 있다.
ex)
import { useState } from "react";
type Todo = {
id: string;
isDone: boolean;
};
// 부모 컴포넌트
function App() {
const [todos, setTodos] = useState<Todo[]>([]);
return (
<>
{todos.map(({ id }) => (
<Todo key={id} id={id} setTodos={setTodos} />
))}
</>
);
}
// 자식 컴포넌트
function Todo({ id, setTodos } : { id: string; setTodos: React.Dispatch<React.SetStateAction<Todo[]>>;})
{
const deleteTodo = () => {
setTodos((prev) => prev.filter((todo) => todo.id !== id));
};
return <div onClick={deleteTodo}></div>;
}
export default App;
1️⃣ setTodos를 prop으로 넘겨줄 때, 어떤 타입인지 알기 어렵다. 이때 setTodos위에 마우스를 올려보면,
React.Dispatch<React.SetStateAction<Todo[]>>
타입임을 알 수 있다.
setTodos: React.Dispatch<React.SetStateAction<Todo[]>>;
2️⃣ setTodos : ()=> void : 반환값이 없는 함수를 콜백함수의 인자로 넘겨준다.
setTodos: (cb :(todo:Todo[])=> Todo[]) => void
▶️ Todo[]를 받아서 Todo[]를 반환하는 콜백을 받은 다음, 아무것도 없는 void로 return 하는 함수를 setTodos에 넣어주는 것을 직관적으로 알아볼 수 있다.
3️⃣ 부모 컴포넌트에서 함수를 선언하고, 해당 함수만 넘겨 줄 때, 어떤 타입인지 마우스 호버로 확인해보자.
import { useState } from "react";
type Todo = {
id: string;
isDone: boolean;
};
// 부모 컴포넌트
function App() {
const [todos, setTodos] = useState<Todo[]>([]);
// 부모 컴포넌트에서 deleteTodo 함수 선언
const deleteTodo = (id: string) => {
const newTodos = todos.filter((todo) => todo.id === id);
setTodos(newTodos);
};
return (
<>
{todos.map(({ id }) => (
<Todo key={id} id={id} deleteTodo={deleteTodo} /> // props로 자식 컴포넌트로 전달
))}
</>
);
}
// 자식 컴포넌트
function Todo({ id, deleteTodo } : {id: string; deleteTodo: (id: string) => void;}) { // props로 받을 때, 타입 지정해주기
const handleOnClick = () => {
deleteTodo(id);
};
return <div onClick={handleOnClick}></div>;
}
export default App;
6. Children Props
예시 1) React.FC<Generic>
: React 18버전 이전
type BaseType = {
id: string;
};
//React 18버전 이전
const Child: React.FC<BaseType> = ({ id }) => {
return <div>{id}</div>;
};
export function Parent() {
return (
<Child id="">
<div>has children</div>
</Child>
);
}
▶️ "암묵적"으로 children으로 넘깁니다. 라는 의미를 가지고 있어 업데이트 이후 잘 사용되지 않음.
예시 2) PropsWithChildren
import { PropsWithChildren } from "react";
type BaseType = {
id: string;
};
function Child({ children }: PropsWithChildren<BaseType>) {
return <div>{children}</div>;
}
export function Parent() {
return <Child id=""></Child>;
}
▶️ prop으로 { children }: PropsWithChildren<BaseType>
을 통해 명시적으로 넘겨준다.
하지만, 아무런 children이 들어가지 않더라도 error가 나지 않는다.
🚨 children? : optional하게 가진다.
ReactNode와 undefined를 동시에 받는다 = children을 아무것도 넣지 않았을 때, 오류를 뱉지 않는다.
예시 3) type StrictChildren<T> = T & { children: ReactNode };
optional이 아닌 children에 ReactNode가 들어가도록, 엄격하게 type을 설정해준다.
import { ReactNode } from "react";
type BaseType = {
id: string;
};
type StrictChildren<T> = T & { children: ReactNode };
function Child({ children }: StrictChildren<BaseType>) {
return <div>{children}</div>;
}
export function Parent() {
return (
<Child id="">
<div>chlidren</div>
</Child>
);
}
7. Utility Type : Omit / Pick
// Person Component
// PersonProps에 5개의 속성을 가지고 있음
export type PersonProps = {
id: string;
description: string;
address: string;
age: number;
profile: string;
};
export const PersonComponent = ({
id,
description,
address,
age,
profile,
}: PersonProps) => {
return (
<>
<PersonChildComponent>
<div>{id}</div>
</PersonChildComponent>
<ProfileComponent
description={description}
address={address}
age={age}
profile={profile}
/>
<AddressComponent address={address} />
</>
);
};
// PersonChild Component
export const PersonChildComponent = ({ children }: PropsWithChildren) => {
return <>{children}</>;
};
// Omit : child 컴포넌트에서 "id" 속성을 제외하고 props으로 받고 싶을 때,
type OmitType = Omit<PersonProps, "id">;
export const ProfileComponent = ({
description,
address,
age,
profile,
}: OmitType) => {
return <></>;
};
// Pick : child 컴포넌트에서 "address" 속성"만" props으로 받고 싶을 때,
type PickType = Pick<PersonProps, "address">;
export const AddressComponent = ({ address }: PickType) => {
return <></>;
};
1) Omit : 특정 속성만 props에서 제외하고 싶을 때 사용
type OmitType = Omit<PersonProps, "id">;
2) Pick : 특정 속성만 props으로 받고 싶을 때 사용
type PickType = Pick<PersonProps, "address">;
'FrontEnd > React' 카테고리의 다른 글
[React + TS] React에서 Typescript 사용하는 방법 알아보기 (1) (0) | 2024.03.08 |
---|---|
[React] React Router Dom (0) | 2024.02.28 |
MacOS Json-server --port 5000 ERROR (0) | 2024.02.20 |
Vite-react ERROR : is missing in props validation (0) | 2024.02.08 |
[React] React Hooks - (2) useEffect (0) | 2024.01.30 |