import React,{useState} from 'react'
const App = ()=>{
const [todos,setTodos] = useState([
{
id:1,
text:'리액트기초 알아보기',
checked:true
},
{
id:2,
text:'컴포넌트 스타일링하기',
checked:true
},
{
id:3,
text:'일정 관리 앱 만들기',
checked:false
},
])
return (
<div>
<TodoTemplate>
<TodoInsert/>
<TodoList todos={todos}/>
</TodoTemplate>
</div>
)
}
import TodoListItem from './TodoListItem'
import './TodoList.scss'
const Todolist = ({todos}) =>{
return (
<div className='TodoList'>
{todos.map(todo=>(
<TodoListItem todo={todo} key={todo.id} />
))}
</div>
)
}
export default Todolist
TodoList에서 todos를 받아와서 map()
을 이용해 todoListItem에 보내주기
import cn from 'classnames'
const TodoListItem= ({todo})=>{
const { text, checked }= 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>
)
}
export default TodoListItem
{cn('checkbox' , true)}
false
인지 class로 저장import { useState, useCallback } from 'react'
const TodoInsert= ()=>{
const [value,setValue] = useState('')
const onChange = useCallback(e=>{
console.log(e.target.value)
setValue(e.target.value)
},[]);
return (
<form className='TodoInsert'>
<input
placeholder='할 일을 입력하세요'
value={value}
onChange={onChange}
/>
<button type='submit'>
<AiFillApple/>
</button>
</form>
)
}
export default TodoInsert
value
를 useState
로 입력을 관리하고onChange
함수를 useCallback Hook
을 사용해서 한 번 함수를 만들고 재사용할 수 있도록 한다. useCallback(()⇒{...},[])
== 컴포넌트가 처음 렌더링될 때만 함수 생성import React,{useState,useCallback,useRef} from 'react'
const nextId = useRef(4)
const onInsert = useCallback(
text=>{
const todo = {
id:nextId.current,
text,
checked:false
};
setTodos(todos.concat(todo))
nextId.current+=1;
},
[todos]
)
return ( ...)
<TodoInsert onInsert={onInsert}/>
const nextId = useRef(4)
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]
)
<form className='TodoInsert' onSubmit={onSubmit}>
onInsert
함수에 현재 value 값을 넣어서 호출하고onInsert
함수에서 value 값을 App.js 에서 text 로 받아 todo를 만들고 추가해준다setValue
로 value를 초기화한다.e.preventDefault();
를 사용해서 새로고침을 방지onClick
이벤트로 만들어도 되는데 굳이 onSubmit
으로 한 이유가 뭔가요?const onRemove = useCallback(
id =>{
setTodos(todos.filter(todo=> todo.id!== id))
},
[todos]
)
<TodoList todos={todos} onRemove={onRemove} />
<TodoListItem todo={todo} key={todo.id} onRemove={onRemove} />
const {id, text, checked }= todo
<div className='remove' onClick={()=>onRemove(id)} >
const onToggle = useCallback(
id=>{
setTodos(
todos.map(todo=>
todo.id === id ? {...todo,checked:!todo.checked} : todo),
)
},[todos]
)
<TodoList todos={todos} onRemove={onRemove} onToggle = {onToggle}/>
todos.map(todo=>todo.id === id ? {...todo,checked:!todo.checked} : todo))
checked
를 바꿔주고 아닌건 그대로 둔다<TodoListItem todo={todo} key={[todo.id](http://todo.id/)} onRemove={onRemove} onToggle={onToggle}/>
const TodoListItem= ({todo,onRemove,onToggle})=>{
<div className={cn('checkbox',{checked})} onClick={()=>{onToggle(id)}}>```