어제 react로 투두리스트를 만들어서 이제는 ts를 결합하여 만들어봤다.
군 컴퓨터는 라이브서버가 안열려서 코드샌드박스에서 코드를 작성했다.
<script>
import "./styles.css";
import TodoList from "../src/TodoList";
import { useState, useRef, useCallback } from "react";
import { Todos } from "../src/model/TodoType";
export default function App(): JSX.Element {
const idRef = useRef(4);
const [value, setValue] = useState<string>("");
const [todos, setTodos] = useState<Todos>([
{
id: 1,
text: "리액트 ts공부하기",
isDone: false
},
{
id: 2,
text: "모듈 내보내기",
isDone: false
},
{
id: 3,
text: "타입설정하기",
isDone: false
}
]);
const onChange = useCallback((e: React.ChangeEvent<HTMLInputElement>) => {
setValue(e.target.value);
}, []);
const onInsert = useCallback(() => {
const newTodo = {
id: idRef.current,
text: value,
isDone: false
};
setTodos((prev) => [...prev, newTodo]);
idRef.current++;
setValue("");
}, [todos, value, idRef.current]);
const onRemove = useCallback(
(id: number) => {
setTodos((prev) => prev.filter((item) => item.id !== id));
},
[todos]
);
return (
<div className="App">
<TodoList todos={todos} onRemove={onRemove} />
<input value={value} onChange={onChange} type="text" />
<button onClick={onInsert}> 추가하기</button>
</div>
);
}
</script>
위 코드는 App.tsx코드이고 함수는 이 곳에 다 몰아놓고 props로 전달했다.
그리고 useState의 값도 그냥 갱신하는게 아닌 함수형 업데이트를 통해 업데이트를 진행했고,
useCallback을 사용해 최적화까지 완료했다.
<script>
import React, { FC } from "react";
import { Todos, Todo } from "../src/model/TodoType";
import TodoItem from "../src/TodoItem";
interface Props {
todos: Todos;
onRemove: (id: number) => void;
}
const TodoList: FC<Props> = ({ todos, onRemove }) => {
return (
<>
{todos.map((todo: Todo) => {
return <TodoItem onRemove={onRemove} key={todo.id} todo={todo} />;
})}
</>
);
};
export default TodoList;
</script>
위는 TodoList 컴포넌트고 함수형 컴포넌트는 모두 FC를 써주는게 좋다.
App.tsx에서 전달받은 프롭스를 통해 화면을 구성하고 다시 프롭스로 데이터를 넘겨준다.
이 때 인터페이스를 통해 함수와 타입을 넘겨주어 프로그래밍이 조금더 원활하게끔 도와준다.
<script>
import React, { FC } from "react";
import { Todo } from "./model/TodoType";
interface Props {
todo: Todo;
onRemove: (id: number) => void;
}
const TodoItem: FC<Props> = ({ todo, onRemove }) => {
const { text, id } = todo;
return (
<li>
{text}
<span
onClick={() => {
onRemove(id);
}}
>
X
</span>
</li>
);
};
export default TodoItem;
</script>
위코드는 onRemove함수를 받아 요소를 삭제하고 비구조화할당을 이용해 코드의 사용감을 높였다.
간단한 todoList의 경우 type모델링도 간단하다.
<script>
export type Todos = Todo[];
export type Todo = {
id: number;
text: string;
isDone: boolean;
};
</script>
위와같이 타입 모델링을 해주었고 import하여 각각 컴포넌트에서 사용했다.
보통은 rafce를 통해 컴포넌트를 구성했는데 손으로 하나하나 자동완성을 안쓰고 코딩하다보니
조금더 구성에 대한 그리고 사소한 문법에 대한 기본이 부족했구나 싶었다.
또한 임포트에서도 그냥 손으로 다 치다보니 모듈 내보내는것조차 실수를 꽤 많이했다.
함수형 업데이트를 통한 state변경,그리고 FC<프롭스>를 통해 했던 기억들,interface 쓰는 기억,
여러가지들이 슬슬 다시 기억이나고 괜찮다.
조금더 열심히 노력해서 ts와 js ,react의 기본기를 탄탄하게 다져야겠다.