$ yarn create react-app todo-app
https://react-icons.github.io/react-icons/
input {
&::placeholder{
color: colar;
}}
button {
transition:0.1s background ease-in;
&:hover{
background:#yellow;
}}
.TodoListItem{
&:nth-child(even){
background: #red;
}
.checkbox{
svg{
font-size:1.5rem;
}
&.checked{
svg{
color:blue;
}
.text{
text-decoration:line-through;
}
}
&+&{
border-top:1px solid #black;
}
웬만한 state 관리 는 최상위 컴포넌트인 App.js 에서 하는게 유리하다
const [todos,setTodos]= useState([
{id:1,
text:'리액트하기',
checked:true},
{id:2,
text:'리액트또하기기',
checked:false},
])
<TodoList todos={todos}/>
const TodoList = (todos)=>{
return (
<div className="TodoList">
{todos.map(todo=>(
<TodoListItem todo={todo} key={todo.id} />
)
)}
</div>
)
}
import cn from 'classnames'
const TodoListItem =(todo)=>{
const {text,checked,id} = todo
return (
<div className='TodoListItem'>
<div className={cn('checkbox',{checked})}>
{checked? <MdCheckBox/>:<MdCheckBoxOutlineBlank/>}
<div className='text'>{text}</div>
</div>
<div className='remove'>
<MdRemoveCircleOutline/>
</div>
</div>
)
}
<div className={cn('checkbox',{checked})}>
처럼 사용가능 일반 형 ‘checkbox’
값이 true일 때만 나오는 형태{checked}
{checked? <MdCheckBox/>:<MdCheckBoxOutlineBlank/>}
const TodoInsert = (**{onInsert}**)=>{
const [value,setValue] = useState('')
const onChange = useCallback((e)=>{
setValue(e.target.value)
},[])
const onSubmit = useCallback(
e=>{
**onInsert(value)**
setValue('')
e.preventDefault();
}
,[onInsert,value])
return (
<>
<form onSubmit={onSubmit} className='TodoInsert'>
<input
value = {value}
onChange={onChange}
placeholder='할일을 입력하세요'/>
<button onClick={onSubmit} type='submit'>
<FaFly/>
</button>
</form>
</>
)
}
onInsert()
를 만들어 보내줘야한다.const nextId = useRef(4);
const onInsert = useCallback(
text=>{
const todo= {
id:nextId.current,
text,
checked:false
}
setTodos(todos.concat(todo))
nextId.current+=1;
}
,[todos])
onInsert(data)
)<TodoInsert onInsert={onInsert}>
로 보내주기const onRemove = useCallback(
id => {
const newtodos = todos.filter(todo=>todo.id!==id)
setTodos(newtodos)
},[todos]
)
<TodoList onRemove={onRemove}>
로 보내주기const TodoList =({todos,onRemove})=> { ...
<TodoListItem ... onRemove={onRemove} />}
<div onClick={()=>onRemove(id)} className='remove'>
<MdRemoveCircleOutline/>
</div>
onClick = {()⇒onRemove(id)}
const onToggle = useCallback(
id =>{
setTodos(
todos.map(todo=>todo.id === id ?
{...todo,checked:!todo.checked}:todo)
)
},[todos])
{...todo,checked:!todo.checked}
로 todo를 똑같이 만들고 check만 바꿔준다<TodoList onToggle={onToggle} onRemove={onRemove} todos={todos}/>
로 내려준다.const TodoList =({todos,onRemove,onToggle})=> { ...
<TodoListItem onToggle={onToggle} onRemove={onRemove} todo={todo} key={todo.id} />
}
<div onClick={()=>onToggle(id)} className={cn('checkbox',{checked})}>...
</div>
CRUD의 모든 기능이 구현되었다 . Todo만 반복 숙달되면 다른 것도 쉽게 만들 수 있을 것 같다.