728x90
반응형
Lv1
- React를 이용한 TodoList를 만듭니다.
- Todo를 Create, Delete, Update(완료/취소) 가 가능해야 합니다.
- 이때, useState와 Props만을 사용합니다.
Keyword
props drilling, state 끌어올리기
1. 프로젝트 생성
: npx create-react-app my-first-ts-app --template typescript
2. 코드 작성
[App.tsx]
1) useState를 사용하는 todos의 타입 지정하기
import { useState } from 'react';
import './App.css';
import InputForm from './components/InputForm';
import uuid from 'react-uuid';
import Content from './components/Content';
export type Todo = {
id: string;
title: string;
content: string;
isDone: boolean;
};
function App() {
const initialState: Todo = {
id: uuid(),
title: '제목1',
content: '내용1',
isDone: false,
};
const [todos, setTodos] = useState<Todo[]>([initialState]);
return (
<StDiv>
<StHeader>
<p>My Todo List📝</p>
<p>React</p>
</StHeader>
<StMain>
<InputForm todos={todos} setTodos={setTodos} />
<Content todos={todos} setTodos={setTodos} isDone={false} />
<Content todos={todos} setTodos={setTodos} isDone={true} />
</StMain>
<footer></footer>
</StDiv>
);
}
export default App;
1) useState<타입> : Todo[ ] : 배열 안 객체
2) useState 초기값 : [initialState] : 배열 안 객체
3) Todo Type은 다른 컴포넌트에서 사용하도록 export 하기
[InputForm.tsx]
2) 컴포넌트에서 props로 전달받은 데이터 타입 지정하기
import React, { PropsWithChildren, useState } from 'react';
import uuid from 'react-uuid';
import { Todo } from '../App';
type Props = {
todos: Todo[];
setTodos: React.Dispatch<React.SetStateAction<Todo[]>>;
};
function InputForm({ todos, setTodos }: Props) {
const [title, setTitle] = useState<string>('');
const [content, setContent] = useState<string>('');
const inputTitle = (e: React.ChangeEvent<HTMLInputElement>) => {
setTitle(e.target.value);
};
const inputContent = (e: React.ChangeEvent<HTMLInputElement>) => {
setContent(e.target.value);
};
const formSubmit = (e: React.FormEvent<HTMLFormElement>) => {
e.preventDefault();
if (title === '' || content === '') {
alert('제목/내용 모두 입력해야합니다.');
return;
}
const newData = {
id: uuid(),
title,
content,
isDone: false,
};
setTodos([...todos, newData]);
setTitle('');
setContent('');
};
return (
<StForm onSubmit={formSubmit}>
<label>제목</label>
<input value={title} onChange={inputTitle}></input>
<label>내용</label>
<input value={content} onChange={inputContent}></input>
<button type="submit">추가하기</button>
</StForm>
);
}
export default InputForm;
1) props로 가져오는 데이터 : {todos, setTodos} : Props=>type Props
2) 이벤트 핸들러 타입 지정하기
▼ 이벤트 핸들러 타입 모를때 찾는 방법 ▼
[Content.tsx]
3) 컴포넌트에서 props로 전달받은 데이터 타입 지정하기
import React from 'react';
import { Todo } from '../App';
import styled from 'styled-components';
type Props = {
todos: Todo[];
setTodos: React.Dispatch<React.SetStateAction<Todo[]>>;
isDone: boolean;
};
function Content({ todos, setTodos, isDone }: Props) {
return (
<>
<StDiv> {isDone ? '✌️Done✌️' : '✍️Working'}</StDiv>
<StDivLayout>
{todos
.filter((item) => item.isDone === isDone)
.map((todo) => {
return (
<StDivTodo key={todo.id}>
<h3>{todo.title}</h3>
<p>{todo.content}</p>
<StDivBtn>
<DeleteButton
onClick={(e: React.MouseEvent<HTMLButtonElement>) => {
const deleted = todos.filter((item) => {
return todo.id !== item.id;
});
setTodos(deleted);
}}
>
삭제
</DeleteButton>
<StateButton
onClick={(e: React.MouseEvent<HTMLButtonElement>) => {
const stateChange = todos.map((item) => {
if (item.id === todo.id) {
return { ...item, isDone: !item.isDone };
} else {
return item;
}
});
setTodos(stateChange);
}}
>
{isDone ? '취소' : '완료'}
</StateButton>
</StDivBtn>
</StDivTodo>
);
})}
</StDivLayout>
</>
);
}
export default Content;
반응형
'TIL :: Today I Learned' 카테고리의 다른 글
TypeScript : 투두리스트 만들기 (3단계 - Json-server) (0) | 2023.12.16 |
---|---|
TypeScript : 투두리스트 만들기 (2단계 - Redux Toolkit) (1) | 2023.12.15 |
리액트 : Modal 모달 팝업 외부 영역 클릭시 닫기 기능 + 배경 스크롤 막기 (0) | 2023.12.11 |
리액트 : 파이어베이스 데이터 저장 후 홈 화면 리랜더링하기 (0) | 2023.12.11 |
리액트 : 카카오 지도 Web API 사용하기 (0) | 2023.12.08 |