1. global.d.ts
Todo List를 만들 때, Todo 객체는 여러 컴포넌트에서 쓰일 것이므로 Todo 객체의 타입은 전역적으로 설정해주면 효율적일 것이다.
- `global.d.ts` 파일은 TypeScript에서 전역으로 사용할 타입들을 선언하는 파일이다.
- 일반적으로 `.d.ts` 확장자를 가진 파일들은 TypeScript 타입 선언 파일로서, 프로젝트 전체에서 사용되는 타입들을 정의하기 위해 사용된다.
1) 내가 작성한 global.d.ts 파일
// global.d.ts
import { Dispatch, SetStateAction } from "react";
export interface Todo {
id: string;
title: string;
content: string;
isDone: boolean;
}
export interface TodosProps {
todos: Todo[];
setTodos: Dispatch<SetStateAction<Todo[]>>;
}
보통 타입 선언 파일에서는 `declare` 키워드를 이용해서 타입을 선언한다고 하는데, `declare`로 선언해주고 작업을 진행하니 계속해서 오류가 발생하여 `declare`를 빼고 그냥 export 해주었다.
2) declare
- `declare` 키워드는 주로 외부 모듈이나 라이브러리의 타입 선언을 지정하는데 사용된다.
- 따라서 `declare` 키워드는 내부 모듈이나 파일에서 사용하지 않아야 한다.
- 나는 현재 내부 컴포넌트들에서만 Todo와 TodoProps의 타입을 사용하고 있기 때문에 declare로 선언해주면 안되는 것이다.
3) 내부 모듈과 외부 모듈?
- 내용을 찾아서 읽어보았으나 아직 잘 이해가 가지 않는다. 아래 링크에 자세히 설명되어있으니, 나중에 다시 반복해서 읽어볼 것
타입스크립트 모듈 & 네임스페이스 시스템 이해하기
2. 이벤트 타입지정
1) 내가 작성한 AddTodo.tsx 파일
// AddTodo.tsx
import React, { useState } from "react";
import { Todo, TodosProps } from "components/config/global";
import shortid from "shortid";
import { styled } from "styled-components";
const AddTodo = ({ todos, setTodos }: TodosProps) => {
const initialState = { id: shortid(), title: "", content: "", isDone: false };
const [todo, setTodo] = useState(initialState);
// 이벤트 타입 지정
const onChange = (e: React.FormEvent<HTMLInputElement>) => {
const { name, value } = e.currentTarget;
setTodo({ ...todo, [name]: value });
}
const onSubmit = (e: React.FormEvent<HTMLFormElement>) => {
e.preventDefault();
setTodos([...todos, { ...todo, id: shortid() }]);
setTodo(initialState);
}
return (
<>
<StAddFormWrapper>
<StAddForm onSubmit={onSubmit}>
<StAddHeader>
<h2>Add</h2>
<StAddBtn>+</StAddBtn>
</StAddHeader>
<StInputTitle
name="title"
value={todo.title}
onChange={onChange}
placeholder="제목을 입력하세요."
required
/>
<StInputContent
name="content"
value={todo.content}
onChange={onChange}
placeholder="내용을 입력하세요."
required
/>
</StAddForm>
</StAddFormWrapper>
</>
);
};
export default AddTodo;
const StAddFormWrapper = styled.div`
width: 80%;
height: 10vh;
position: absolute;
bottom: 0;
display: flex;
flex-direction: column;
justify-content: center;
`;
const StAddForm = styled.form`
display: flex;
flex-direction: column;
justify-content: center;
`
const StAddHeader = styled.div`
display: flex;
justify-content: space-between;
`
const StAddBtn = styled.button`
outline: none;
border: none;
background-color: none;
font-size: 18px;
font-weight: 700;
`
const StInputTitle = styled.input`
height: 25px;
outline: none;
border: none;
border-bottom: 1px solid gray;
`;
const StInputContent = styled.input`
height: 25px;outline: none;
border: none;
border-bottom: 1px solid gray;
`
- `e: React.FormEvent<HTMLInputElement>`, `e: React.FormEvent<HTMLFormElement>`는 React에서 이벤트 핸들러 함수를 정의할 때 사용하는 타입이다.
- e: 이벤트 객체 (Event Object)
- React.MouseEvent: 마우스 이벤트를 나타내는 타입
- <HTMLInputElement>: 이벤트가 발생하는 엘리먼트의 타입. 여기서는 <input>에서 발생한 이벤트를 처리하므로 HTMLInputElement로 지정된다.
- 따라서 e: React.MouseEvent<HTMLButtonElement>는 버튼 엘리먼트에서 발생한 마우스 이벤트 객체를 나타낸다. 이벤트 핸들러 함수 내에서 이벤트 객체를 사용하여 버튼 클릭과 같은 동작을 처리할 수 있다.
참고 블로그 - [typescript] 타입스크립에서 이벤트 객체 타입 지정하기
2) SyntheticEvent (합성 이벤트)
이벤트 핸들러는 모든 브라우저에서 이벤트를 동일하게 처리하기 위한 이벤트 래퍼 SyntheticEvent 객체를 전달받는다.
- Keyboard Events
- ex) onKeyDown, onKeyPress, onKeyUp
- Focus Events
- ex) onFocus, onBlur
- Form Events
- ex) onSubmit, onChange, onInput, onInvalid, onReset
- Generic Events
- ex) onError, onLoad
자세한 내용 참고 - SyntheticEvent - React
'✍️ What I Learned > TIL' 카테고리의 다른 글
[TIL] Redux toolkit - createAction, createReducer, configureStore, createSlice (0) | 2023.08.01 |
---|---|
[TIL] 중첩 라우팅(Nested Routes) (feat. React-Router-DOM v6) (0) | 2023.07.31 |
[TIL] TypeScript + React 개발환경 세팅 (0) | 2023.07.27 |
[TIL] TypeScript 언어의 탄생 배경 기본적인 특징 (0) | 2023.07.25 |
[TIL] React Query 세팅, isLoading/isError, staleTime vs. cacheTime (0) | 2023.07.17 |