Props로 작업하기
App.tsx
import React from "react";
import TodoList from "./components/TodoList";
// 1
const App: React.FC = () => {
const todos = [{ id: "t1", text: "타입스크립트 공부 마무리" }];
return (
<div className="App">
<TodoList items={todos} /> // 2
</div>
);
};
export default App;
- 리액트에서 제공하는 Function Component 타입이고 JSX를 리턴합니다.
- TodoList 컴포넌트로 todos를 전달합니다.
TodoList.tsx
import React from "react";
// 1
interface TodoListProps {
items: {id: string, text: string}[];
}
// 1
const TodoList: React.FC<TodoListProps> = props => {
return (
<ul>
// 2
{props.items.map((todo) => (
<li key={todo.id}>{todo.text}</li>
))}
</ul>
);
};
export default TodoList;
- 컴포넌트 안에서 프롭을 사용한다면 타입스크립트에게 이 프롭들이 어떻게 생겼고 어떤 구조를 갖고 있는지 알려줘야 한다는 것입니다. 따라서 인터페이스를 통해 프롭의 구조를 설명하고 제네릭 타입으로 컴포넌트에 알려줍니다.
- 프롭 배열의 수만큼 매핑하여 리스트를 나열합니다.
"ref"로 사용자 입력받기
NewTodo.tsx
import React, { useRef } from "react";
const NewTodo: React.FC = () => {
// 1
const textInputRef = useRef<HTMLInputElement>(null);
const todoSubmitHandler = (event: React.FormEvent) => {
event.preventDefault();
const enteredText = textInputRef.current!.value; // 2
};
return (
<form onSubmit={todoSubmitHandler}>
<div>
<label htmlFor="todo-text">할 일 목록</label>
<input type="text" id="todo-text" ref={textInputRef} />
</div>
<button type="submit">추가</button>
</form>
);
};
export default NewTodo;
- 이 ref안에 어떤 데이터가 저장될지 아는 것이 중요합니다. 지금은 input element이고 기본값은 null입니다.
- null일 수 있기에 느낌표(!)로 타입스크립트에게 이 값이 잘 설정될 것이라고 알립니다.
Cross-component 커뮤니케이션 & 상태 관리
todo.model.ts
export interface Todo {
id: string;
text: string;
}
App.tsx
import React, { useState } from "react";
import TodoList from "./components/TodoList";
import NewTodo from "./components/NewTodo";
import { Todo } from "./todo.model";
const App: React.FC = () => {
const [todos, setTodos] = useState<Todo[]>([]); // 1
const todoAddHandler = (text: string) => {
// 2
setTodos((prevTodos) => [
...prevTodos,
{ id: Math.random().toString(), text: text },
]);
};
return (
<div className="App">
<NewTodo onAddTodo={todoAddHandler} />
<TodoList items={todos} />
</div>
);
};
export default App;
NewTodo.tsx
import React, { useRef } from "react";
// 3
type NewTodoProps = {
onAddTodo: (todoText: string) => void;
}
// 3
const NewTodo: React.FC<NewTodoProps> = props => {
const textInputRef = useRef<HTMLInputElement>(null);
const todoSubmitHandler = (event: React.FormEvent) => {
event.preventDefault();
const enteredText = textInputRef.current!.value;
props.onAddTodo(enteredText);
};
return (
<form onSubmit={todoSubmitHandler}>
<div>
<label htmlFor="todo-text">할 일 목록</label>
<input type="text" id="todo-text" ref={textInputRef} />
</div>
<button type="submit">추가</button>
</form>
);
};
export default NewTodo;
- useState를 이용하여 상태를 관리하고 초기값이 없기에 todos의 구조를 인터페이스로 정의하여 제네릭으로 연결합니다.
- 배열과 스프레드 문법으로만 구현하면 리액트 상태 업데이트 일정상 최신 상태가 아닐 수 도 있기에 함수에 함수를 전달해 상태를 업데이트해 최신 스냅샷을 보장받습니다.
- 프롭 함수의 구조를 타입으로 정의하고 제네릭으로 연결합니다.
'TYPESCRIPT' 카테고리의 다른 글
장소 선택 및 공유 구글 API 연습 (5) | 2023.04.10 |
---|---|
웹팩(Webpack) 사용하기 (6) | 2023.04.07 |
모듈과 네임스페이스 (6) | 2023.04.06 |
연습 프로젝트 4 (6) | 2023.04.04 |
연습 프로젝트 3 (6) | 2023.04.03 |