(1)에서의 프로젝트는 기본 외관만 짠 상태로 빈 껍데기입니다.
상태 관리를 통해 프로젝트를 실제로 작동시켜보겠습니다.
class App extends Component{
state = {
input: ''
}
handleChange = (e) => {
const { value } = e.target;
this.setState({
input: value
});
}
render(){
const {input} = this.state;
const{
handleChange
} = this;
return(
<PageTemplate>
<TodoInput value={input} onChange={handleChange}/>
<TodoList/>
</PageTemplate>
);
}
}
App.js에
todos: [ {id : 0, text: '리액트 공부하기', done:true}, {id : 1, text: '컴포넌트 스타일링 해보기', done:false} ] <TodoList todos ={todos}/>
TodoList로 todos 넘겨준 뒤, map이용하여 배치.
class TodoList extends Component{
render(){
const {todos} = this.props;
const todoList = todos.map(
todo=>(
<TodoItem
key={todo.id}
done={todo.done}>
{todo.text}
</TodoItem>
)
);
return(
<div>
{todoList}
</div>
);
}
}
id=1
getId=()=>{
return ++this.id;
}
handleInsert=()=>{
const{todos, input} = this.state;
const newTodo = {
text:input,
id: this.getId(),
done:false
}
this.setState({
input:'',
todos : [...todos,newTodo]
});
}
handleToggle =(id) =>{
const {todos} = this.state;
const index = todos.findIndex(todo => todo.id===id);
const toggled ={
...todos[index],
done: !todos[index].done
}
this.setState({
todos:[
...todos.slice(0,index),
toggled,
...todos.slice(index+1, todos.length)
]
});
}
todo=>(
<TodoItem
key={todo.id}
done={todo.done}
onToggle={() => onToggle(todo.id)}>
{todo.text}
</TodoItem>
)
handleRemove = (id) =>{
const {todos} = this.state;
const index = todos.findIndex(todo => todo.id===id);
this.setState({
todos:[
...todos.slice(0,index),
...todos.slice(index+1,todos.length)
]
});
}
onRemove={() => onRemove(todo.id)}>
🧨 onClick이벤트는 부모, 자식 모두 설정되어있어 자식 -> 부모 순으로 메서드를 실행.
이를 방지하기 위해서 자식 요소의 onClick 처리 함수 내부에 e.stopPropagation 함수를 호출해준다.
<div className={cx('todo-item')} onClick={onToggle}>
<input className={cx('tick')} type="checkbox" checked={done} readOnly/>
<div className={cx('text', { done })}>{children}</div>
<div className={cx('delete')} onClick={(e) => {
onRemove();
e.stopPropagation();
}
}>[지우기]</div>
</div>
참고 : <리액트를 다루는 기술>