반응형
React with TypeScript
- 설치
npx create-react-app 프로젝트 이름 --template typescript
- 리액트는 jsx문법을 사용하기 때문에 typescript를 사용할 때 확장자명을 ts가 아닌 tsx로 사용한다(컴포넌트를 생성하는 게 아니라면 ts로 작성해도 됨).
props의 타입 지정 : React.FC
- props의 타입을 Generics로 지정한다. -> FC 자체가 Generics 타입이다.
- React.FC를 사용하면 props에 기본적으로 children 이 들어가 있고, 컴포넌트의 defaultProps, propTypes, contextTypes를 설정할 때 자동완성 기능을 이용할 수 있다.
- React.FC가 이미 제네릭 타입이기 때문에 타입은 이미 정의된 것이다.
- <{}>은 제네릭 타입을 만드는 구문이다. 안에 필요한 props의 타입을 지정한다.이를 통해 이 컴포넌트를 위해 만든 props와 children 같은 기본적인 props가 합쳐진다.
// React.FC 사용
const Todos: React.FC<{ items: Todo[]; onRemoveTodo: () => void }> = props => {
return (
<ul>
{props.items.map(item => (
<li key={item}>{item}</li>
))}
</ul>
);
};
// React.FC 사용 x
const Todos = (props: { items: string[], children: ...}) => {
return (
<ul>
{props.items.map(item => (
<li key={item}>{item}</li>
))}
</ul>
);
};
데이터 모델 추가
컴포넌트나 데이터를 잘못 이용할 경우를 방지해 준다.
export interface Todo {
id: string;
text: string;
}
const Todos: React.FC<{ items: Todo[] }> = props => {
return (
<ul>
{props.items.map(item => (
<li key={item}>{item}</li>
))}
</ul>
);
};
typescript의 양식 제출
// form submit event type
event: React.FormEvent
// onClick event type
event: React.MouseEvent
typescript의 ref와 useRef
- 이 ref가 입력창에 연결될 거라는 것을 명시해야 한다. -> 제네릭 타입으로 정의해야 한다.
- useRef 자체가 제네릭 타입으로 되어있다.
- button이라면 HTMLButtonElement, paragraph라면 HTMLParagraphElement을 사용한다.
- 시작값을 null로 지정해야 한다.
# 연산자 !
- 뒤에 느낌표를 붙이면 앞의 값이 확실히 null이나 undefined가 아니라는 걸 알린다.
- null 일 수 없다고 100% 확신하는 경우에만 사용한다.
# 연산자 ?
- null 일 경우, 상수 또는 값을 저장할 곳에 null을 저장한다.
const todoTextInputRef = useRef<HTMLInputElement>(null);
const submitHandler = (event: React.FormEvent) => {
event.preventDefault();
const enteredText = todoTextInputRef.current!.value;
}
return(
...
<form onSubmit={submitHandler}
<input type="text" id="text" ref={todoTextInputRef}>
...
</form>
)
함수 props 타입 지정
const NewTodo: React.FC<{onAddTodo: (text: string) => void}> = props => {
...
state 타입 지정
// setTodos의 타입 => dispatch
// useState의 타입 => 제네릭
const [todos, setTodos] = useState<Todo[]>([]);
# bind
실행할 함수를 미리 설정할 수 있는 메서드
// 첫번째 아규먼트: this가 무엇을 가르키는지 설정
// 두번째 아규먼트: 함수가 매개변수로 받는 값 설정
onRemoveTodo = {props.onRemoveTodo.bind(null, item.id)}
Context API
// store/todos-context.tsx
import React, { useState } from 'react';
import Todo from '../models/todo';
type TodosContextObj = {
items: Todo[];
addTodo: (text: string) => void;
removeTodo: (id: string) => void;
};
// createContext => 제네릭 타입
export const TodosContext = React.createContext<TodosContextObj>({
items: [],
addTodo: () => {},
removeTodo: (id: string) => {},
});
const TodosContextProvider: React.FC = (props) => {
const [todos, setTodos] = useState<Todo[]>([]);
const addTodoHandler = (todoText: string) => {
const newTodo = new Todo(todoText);
setTodos((prevTodos) => {
return prevTodos.concat(newTodo);
});
};
const removeTodoHandler = (todoId: string) => {
setTodos((prevTodos) => {
return prevTodos.filter((todo) => todo.id !== todoId);
});
};
const contextValue: TodosContextObj = {
items: todos,
addTodo: addTodoHandler,
removeTodo: removeTodoHandler,
};
return (
<TodosContext.Provider value={contextValue}>
{props.children}
</TodosContext.Provider>
);
};
export default TodosContextProvider;
// Todos.tsx
import { userContext } from 'react';
import { TodosContext } from '../store/todos-context';
const todosCtx = useContext(TodosContext);
// App.tsx
import TodosContextProvider from './store/todos-context';
return(
<TodosContextProvider>
<NewTodo />
<Todos />
</TodosContextProvider>
)
반응형
'온라인 강의(유데미, 인프런 등) > React 완벽 가이드(유데미)' 카테고리의 다른 글
[NextJS] NextJS 개념 정리 (0) | 2023.03.10 |
---|---|
[typescript] tsconfig.json (0) | 2023.03.09 |
[typescript] typescript 개념 정리(1) (0) | 2023.03.08 |
[react] React Router v6.4 loader/action/fetchers (0) | 2023.03.08 |
[react] 절대경로/상대경로 & React에서 import시 절대경로 사용하기 (0) | 2023.03.07 |