HOMEWORK
Todos
TodoForm TodoList
상태변수 : text TodoItem
포커스 삭제 버튼 : onDelete
추가버튼 : submit
seq를 잡아서 같은 공부하기가 두 개 들어간 상태에서 하나 지우면 하나만 지워지게 해야한다.
css
TodoForm.module.css
.TodoForm {
text-align: center;
padding: 40px 0;
background: beige;
}
.TodoForm input {
width: 300px;
height: 35px;
padding: 0 20px;
box-sizing: border-box;
vertical-align: top;
border: 1px solid #dcdcdc;
}
.TodoForm button {
width: 80px;
height: 35px;
border: none;
}
TodoList.module.css
.TodoList {}
.TodoList li {
padding: 15px 30px;
border-bottom: 1px solid #dcdcdc;
background: tomato;
}
.TodoList li span {
margin-right: 20px;
font-size: 16px;
color: #fff ;
cursor: pointer;
}
.TodoList li em {
color: #fff;
cursor: pointer;
}
.TodoList li button {
float: right;
width: 80px;
}
.TodoList li.on span {
color: yellow;
}
.TodoList li.on em {
color: yellow ;
text-decoration: line-through;
}
Todos.module.css
.Todos {
width: 450px;
margin: 10px auto;
}
.Todos h1 {
text-align: center;
padding: 10px 0;
font-size: 20px;
}
Todos.jsx
import React from 'react';
import { useRef } from 'react';
import { useState } from 'react';
import TodoForm from './TodoForm';
import TodoList from './TodoList';
import myStyle from '../css/Todos.module.css';
const Todos = () => {
const [text, setText] = useState('');
const textRef = useRef();
const seq = useRef(1);
const [list, setList] = useState([]);
const onInput = (e) => {
const {value} = e.target;
setText(value);
}
const onAdd = (e) => {
e.preventDefault();
if(!text)
return;
setList([
...list,
{
id: seq.current++,
text: text,
},
])
setText('');
textRef.current.focus();
}
const onDelete = (id) => {
console.log(id);
setList(list.filter(item => item.id !== id))
};
return (
<div className={myStyle.Todos}>
<h1>일정관리</h1>
<TodoForm text={text} seq={seq} textRef={textRef} onInput={onInput} onAdd={onAdd}/>
<TodoList list={list} seq={seq} onDelete={onDelete}/>
</div>
);
};
export default Todos;
TodoForm.jsx
import React from 'react';
import myStyle from '../css/TodoForm.module.css';
const TodoForm = ({text, textRef, onInput, onAdd}) => {
return (
<div className={myStyle.TodoForm}>
<form onSubmit={ onAdd }>
<input type='text' name='text' value={ text } onChange={ onInput } ref={textRef}/>
<button type='submit'>추가</button>
</form>
</div>
);
};
export default TodoForm;
TodoList.jsx
import React from 'react';
import TodoItem from './TodoItem';
import myStyle from '../css/TodoList.module.css';
const TodoList = ({list, seq, onDelete}) => {
return (
<div className={myStyle.TodoList}>
<ul>
{
list.map(item => <TodoItem key={seq} item={item} onDelete={onDelete}/>)
}
</ul>
</div>
);
};
export default TodoList;
TodoItem.jsx
import React from 'react';
const TodoItem = ({ item, onDelete }) => {
return (
<div>
<li>
{item.text}
<button onClick={() => onDelete(item.id)}>삭제</button>
</li>
</div>
);
};
export default TodoItem;
강사님 답
상태변수와 상태변수를 바꾸는 함수는 같이 있는게 좋다 !!!!
모든 상태변수를 부모가 가지고 있을 필요는 없다.
Todos.jsx
import React from 'react';
import { useRef } from 'react';
import { useState } from 'react';
import TodoForm from './TodoForm';
import TodoList from './TodoList';
import myStyle from '../css/Todos.module.css';
import TodoItem from './TodoItem';
const Todos = () => {
const [list, setList] = useState([]);
const seq = useRef(1);
const onAdd = (text) => {
setList([
...list,
{
seq: seq.current++,
text: text,
},
])
}
const onDel = (seq) => {
console.log(seq);
setList(list.filter(item => item.seq !== seq))
};
return (
<div className={myStyle.Todos}>
<h1>일정관리</h1>
<TodoForm onAdd={ onAdd }/>
<TodoList list={ list } onDel={ onDel }/>
</div>
);
};
export default Todos;
TodoForm.jsx
text는 여기서만 쓰므로 여기에 선언하면 된다 !!
import React, { useRef, useState } from 'react';
import myStyle from '../css/TodoForm.module.css';
const TodoForm = ({ onAdd }) => {
const [text, setText] = useState('');
const textRef = useRef();
const onInput = (e) => {
const {value} = e.target;
setText(value);
}
const onSubmit = (e) => {
e.preventDefault();
if(!text)
return;
onAdd(text); //입력한 text를 list에 추가
setText('');
textRef.current.focus();
}
return (
<div className={myStyle.TodoForm}>
<form onSubmit={ onSubmit }>
<input type='text' name='text' value={ text } onChange={ onInput } ref={textRef}
placeholder='해야할 일을 입력하세요.'/>
<button type='submit'>추가</button>
</form>
</div>
);
};
export default TodoForm;
import React from 'react';
import TodoItem from './TodoItem';
import myStyle from '../css/TodoList.module.css';
const TodoList = ({list, onDel}) => {
return (
<div className={myStyle.TodoList}>
<ul>
{
list.map(item => <TodoItem key={item.seq} item={item} onDel={onDel}/>)
}
</ul>
</div>
);
};
export default TodoList;
import React from 'react';
const TodoItem = ({ item, onDel }) => {
const { seq, text } = item
return (
<div>
<li>
{ text }
<button onClick={() => onDel(seq)}>삭제</button>
</li>
</div>
);
};
export default TodoItem;
이런식으로 삭제되고 새로 만들어도
한 번 만들어진 seq는 또 만들어지지 않는다.
대신 새로고침하면 seq가 새롭게 랜더링돼서 1부터 다시 시작하는 문제가 있다.
const seq = useRef(list.length + 1);
그래서 이걸로 바꿨는데 이것도 좀 꼬여서 어차피 나중에 DB가서 하면 이건 상관없어지니
일단 넘어갔다~
'REACT' 카테고리의 다른 글
DAY 78 - React - useReducer / React-Router/ JSX (2024.10.28) (0) | 2024.10.28 |
---|---|
DAY 77 - React - 데이터 읽기, 쓰기 / 비동기통신(aixos) / useMemo (2024.10.25) (0) | 2024.10.27 |
DAY 76 - React - Hook: useEffect / 컴포넌트별 CSS (2024.10.24) (3) | 2024.10.24 |
DAY 75 - React / HOMEWORK (2024.10.23) (3) | 2024.10.23 |
DAY 74 - React (2024.10.22) (2) | 2024.10.22 |