티스토리 뷰
클래스형 컴포넌트
//ClassCom
import { Component } from "react";
class ClassCom extends Component {
render() {
return (
<div>
클래스형 컴포넌트
</div>
);
}
}
export default ClassCom;
extends는 상속받는다 라는 의미 : Component라는 클래스로부터 상속을 받겠다
사용 방법 : Component를 extends해야 하고, render()를 호출
마지막엔 export문을 사용 후 불러오는 파일엔 import를 사용
함수형 컴포넌트
//FuncCom.tsx
import React from 'react';
function FuncCom()
{
return(
<div>
함수형 컴포넌트
</div>
)
}
export default FuncCom;
//FuncCom.tsx
import React from 'react';
const FuncCom = () =>
{
return(
<div>
함수형 컴포넌트
</div>
)
}
export default FuncCom;
App.tsx에서
//App.tsx
import React from 'react';
import logo from './logo.svg';
import './App.css';
import ClassCom from './ClassCom';
import FuncCom from './FuncCom';
function App() {
let name = '리액트';
return (
<div>
<ClassCom></ClassCom>
<FuncCom></FuncCom>
</div>
);
}
export default App;

state
const TodoList : React.FC = () =>
{
const title : string = '오늘 할일'
자바스크립트는 타입을 그렇게 중요시 생각하지 않지만 타입스크립트는 타입이 굉장히 중요하다.
React.FC의 FC뜻은 함수형 컴포넌트이다.
>> 리액트는 const같은 변수를 사용하기 보다 state를 사용한다.
데이터가 변경되면 즉시 화면에 반영하겠다라는 의미, 상태관리가 가능하다.
useState사용
//const [todos, setTodos] = useState([]);
//todos 현재 할 일 목록 (배열)
//setTodos 할 일 목록을 **변경(업데이트)**하는 함수
//주석문 ...
const TodoList : React.FC = () =>
{
const title : string = '오늘 할일';
//구조분해할당
const[todos, setTodos] = useState<string[]>(['청소하기', '운동하기', '공부하기']);
return (
<div>
<h1>{title}</h1>
<p></p>
<div className='container'>
<ul>
<li>{todos[0]}</li>
<li>{todos[1]}</li>
<li>{todos[2]}</li>
</ul>
</div>
</div>
//...
데이터 반복 처리
for문 사용이 안됨
map을 사용하여 반복 처리
//MapTest.tsx
<div>
<h2>과일</h2>
<ul>
<li>{fruits[0]}</li>
<li>{fruits[1]}</li>
<li>{fruits[2]}</li>
</ul>
</div>
//MapTest.tsx
<div>
<h2>과일</h2>
<ul>
{fruits.map((fruits, index) => (
<li key={index}>{fruits}</li>
))}
</ul>
</div>
이런식으로 map을 활용하여 반복문 작성
index : 루프가 돌면서 값이 순서대로 들어옴
map을 사용한 투두리스트
//Todolist.tsx
import React, { useState } from 'react'
type Todo = {
id: number;
text: string;
isChecked: boolean;
}
const TodoList : React.FC = () =>
{
const title : string = '오늘 할일';
//구조분해할당
const[todos, setTodos] = useState<Todo[]>([
{id: 1, text: '정보처리기사 공부하기', isChecked: false},
{id: 2, text: '타입스크립트 공부하기', isChecked: false},
{id: 3, text: '리액트 공부하기', isChecked: false}
]);
return (
<div>
<h1>{title}</h1>
<p></p>
<div className='container'>
<div className='board'>
<ul>
{todos.map((todo, index) => (
<li key={index}>{todo.text}</li>
))
}
</ul>
</div>
</div>
</div>
)
}
export default TodoList
체크박스 기능 추가(상태 변경)
>> 체크박스를 누르면 글자에 줄 긋기
<span>{/*취소선 표시*/}
{
todo.isChecked
? <del>{todo.text}</del> // 체크됐으면 취소선
: <span>{todo.text}</span> // 아니면 그냥 텍스트
}
</span>
할일 추가하기
** 버튼이 너무 멋이가 없다. >>부트스트랩 다운로드
https://react-bootstrap.netlify.app/docs/getting-started/introduction
Introduction | React Bootstrap
Learn how to include React Bootstrap in your project.
react-bootstrap.netlify.app
npm install react-bootstrap bootstrap
시계 추가하기
// Timer.tsx
import React, { useState } from 'react';
import { Button } from 'react-bootstrap';
// const Timer: React.FC = () => {
// const [seconds, setSeconds] = useState<number>(0);
// const startTimer = () => {
// setInterval(() => {
// setSeconds(prev => prev + 1);
// }, 1000);
// };
// return (
// <div>
// <h2>타이머: {seconds}초</h2>
// <Button onClick={startTimer}>시작</Button>
// </div>
// )
// }
const Clock: React.FC = () => {
const [time, setTime] = useState(new Date());
setInterval(() => {
setTime(new Date());
},1000);
return (
<div>
현재시간 : {time.toLocaleTimeString()}
</div>
)
}
export default Clock;
이번 시간에 만든 Todolist
// TodoList.tsx
import React, { useState } from 'react'
import { Button } from 'react-bootstrap';
type Todo = {
id: number;
text: string;
isChecked: boolean;
}
const TodoList: React.FC = () => {
const title: string = '오늘 할일';
const [todos, setTodos] = useState<Todo[]>([
{ id: 1, text: '정보처리기사 공부하기', isChecked: false },
{ id: 2, text: '타입스크립트 공부하기', isChecked: false },
{ id: 3, text: '리액트 공부하기', isChecked: false }
]);
const [newTodos, setNewTodos] = useState<string>('');
const [showDetail, setShowDetail] = useState<boolean>(false);
const [selectedTodo, setSelectedTodo] = useState<Todo | null>(null);
//항목체크하기
const handleCheckedChange = (id: number) => {
setTodos((prevItems) =>
prevItems.map((item) =>
item.id === id ? { ...item, isChecked: !item.isChecked } : item
)
)
}
//항목추가하기
const addTodo = () => {
if (newTodos.trim() !== '') {
setTodos([...todos, { id: Date.now(), text: newTodos, isChecked: false }]);
setNewTodos('');
}
}
//항목삭제하기
const removeTodo = (id : number) => {
setTodos(todos.filter((todo)=>todo.id !==id))
}
//
const handleTodoClick = (todo : Todo) => {
setShowDetail(true);
setSelectedTodo(todo);
}
const handleClose = () => {
setShowDetail(false);
}
return (
<div>
<h1>{title}</h1>
<div className="container">
<div>
<input
type="text"
placeholder="할 일을 입력하세요."
style={{
marginRight: '10px',
writingMode: 'horizontal-tb'
}}
onChange={(e)=> setNewTodos(e.target.value)}
/>
<Button variant="warning" onClick={addTodo}>추가</Button>
</div>
<div className="board">
<ul>
{todos.map((todo) => (
<li key={todo.id}>
<input
type="checkbox"
checked={todo.isChecked}
onChange={() => handleCheckedChange(todo.id)}
/>
<span onChange={() => handleTodoClick(todo)}>
{todo.isChecked
? <del>{todo.text}</del>
: <span>{todo.text}</span>}
</span>
<button
onClick={()=>
removeTodo(todo.id)}
className='del'
>삭제</button>
</li>
))}
</ul>
</div>
</div>
</div>
);
};
export default TodoList;