📢 useMemo()
👉🏻 리액트에서 컴포넌트 성능을 최적화 하는데 사용되는 훅(Hook).
👉🏻 memo => memoization의 약자로, "메모리에 저장하다"라는 의미.
👉🏻 동일한 계산을 반복해야 할 때, 이전의 값을 메모리에 저장함으로써 반복수행을 제거하여 프로그램 실행 속도를
빠르게 해주는 기술
👉🏻 컴포넌트 렌더링
- 함수형 컴포넌트가 렌더링 => 컴포넌트 함수 호출 => 모든 내부 변수 초기화
👉🏻 useMemo 호출:
- useMemo 렌더링 => 함수 호출 => memoize된 함수를 재사용
📢 Todo List 만들기!
👉🏻 지금까지 배운 것들 활용해서 todoList 만들기
👉🏻 input창에 button 생성
👉🏻 input 값을 입력하고 버튼을 클릭하면 아이템 추가
👉🏻 삭제버튼 구현
👉🏻 각 아이템 클릭시, 취소선(다시 클릭시 사라짐(toggle))
todolist-app이라는 새로운 앱 생성하여 진행
app.js
import './App.css';
import TodoList from './components/TodoList';
import 'bootstrap/dist/css/bootstrap.min.css';
function App() {
return (
<div className="App">
<TodoList />
</div>
);
}
export default App;
components/style.css
.todoList {
max-width: 600px;
margin: 30px auto;
padding: 20px;
background-color: #f4f4f4;
border-radius: 8px;
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
}
.todoList-items {
margin-top: 20px;
}
.todoCreate {
display: flex;
gap: 10px;
margin-bottom: 20px;
}
.todoCreate input {
flex: 1;
padding: 10px;
border: 1px solid #ccc;
border-radius: 4px;
outline: none;
}
.todoCreate input:focus {
border-color: #007bff;
box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.25);
}
.todoCreate button {
padding: 10px 20px;
background-color: #28a745;
color: #fff;
border: none;
border-radius: 4px;
cursor: pointer;
transition: background-color 0.2s ease;
}
.todoCreate button:hover {
background-color: #218838;
}
.todoItem {
padding: 10px;
background-color: #fff;
border: 1px solid #ddd;
border-radius: 4px;
margin-bottom: 10px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}
.todoItem h3{
width: 90%;
margin: 0 auto;
justify-content: space-between;
display: flex;
align-items: center;
text-align: left;
}
.todoItem-text {
cursor: pointer;
flex: 1;
text-decoration: none;
}
.todoItem-text.completed {
text-decoration: line-through;
color: #888;
}
.remove-btn {
background-color: #dc3575;
color: #fff;
border: none;
border-radius: 4px;
padding: 5px 10px;
cursor: pointer;
transition: background-color 0.2s ease;
}
.remove-btn:hover {
background-color: #91234d;
}
.title {
margin: 0 0 20px 0;
font-weight: 700;
font-size: 100px;
font-family: 'Poppins', sans-serif;
color: #333;
text-align: center;
text-transform: uppercase;
letter-spacing: 2px;
background: linear-gradient(90deg, #28a745, #dc3575);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.3);
}
components/Todo.jsx
import React from 'react';
const Todo = ({ todo, onRemove, onToggle }) => {
return (
<div className='todoItem'>
<h3>
<span
className={`todoItem-text ${!todo.active ? 'completed' : ''}`}
onClick={()=> onToggle(todo.id)}
>
{todo.todo}
</span>
{/* function으로 매개변수를 전달할 경우 */}
<button
className='remove-btn'
onClick={()=>onRemove(todo.id)}
>
del
</button>
</h3>
</div>
);
};
export default Todo;
components/TodoCreate.jsx
import React from 'react';
const TodoCreate = ({ todo, onChange, onCreate }) => {
return (
<div className='todoCreate'>
<input
type="text"
name='todo'
onChange={onChange}
value={todo}
/>
<button onClick={onCreate}>add</button>
</div>
);
};
export default TodoCreate;
components/TodoList.jsx
import React, { useState, useRef } from 'react';
import TodoCreate from './TodoCreate';
import Todo from './Todo';
import './style.css';
const TodoList = () => {
const nextId = useRef(0);
const [todos, setTodos] = useState([]);
const [inputs, setInputs] = useState('');
const todo = inputs;
const onChange = (e) =>{
setInputs(e.target.value);
}
const onCreate = ()=>{
const todo = {
id: nextId.current,
todo: inputs,
active: true
};
//현재 users에 user 추가 => concat
setTodos(todos.concat(todo));
// 기존 inputs 창 초기화
setInputs('');
nextId.current += 1 ; //ref() : 재 렌더링이 일어나지 않음.
}
const onRemove=(id) =>{
setTodos(todos.filter(t=>t.id !== id))
}
const onToggle=(id)=>{
setTodos(todos.map(t=>
t.id === id ? {...t, active: !t.active} : t
))
}
return (
<div className='todoList'>
<h1 className='title'>Todo List</h1>
<TodoCreate todo={todo} onChange={onChange} onCreate={onCreate} />
<div className='todoList-items'>
{todos.map(t=>(
<Todo todo={t} key={t.id} onRemove={onRemove} onToggle={onToggle} />
))}
</div>
</div>
);
};
export default TodoList;

'프론트엔드 > React' 카테고리의 다른 글
| useReducer로 상태 관리 (0) | 2024.09.19 |
|---|---|
| Axios와 useEffect를 사용하여 데이터 가져오기 (0) | 2024.09.09 |
| React 배열(array) 및 훅(Hook) (5) | 2024.09.06 |
| React 상태 관리, 라우팅 (0) | 2024.09.06 |
| React 기본 개념 및 컴포넌트와 라우팅 설정하기 (1) | 2024.09.06 |