1편 에 이어서 시작!
1편에서 만들어 놨던 각각의 컴포넌트들을 App.js에 추가 해준 컴포넌트들에서 각각의 리스트 아이템을 보여주기 위해서 훅을 사용한다.
import React, { useState } from 'react';
import './App.css'
import TodoTemplate from './components/TodoTemplate';
import TodoInsert from './components/TodoInsert';
import TodoList from './components/TodoList';
const App = () => {
const [todos, setTodos] = useState([
{
id:1,
contents: '리액트 연습',
check: true
},
{
id:2,
contents: 'todolist',
check: true
}
]);
return (
<div>
<TodoTemplate >
<TodoInsert />
<TodoList todos={todos}/>
</TodoTemplate>
</div>
);
};
export default App;
그러고 나서 TodoList, TodoListItem을 아래와 같이 바꿔준다.
TodoList
import React from "react";
import "./TodoList.css";
import TodoListItem from "./TodoListItem";
const TodoList = ({ todos }) => {
return (
<div className="TodoList">
{todos.map(todo => (
<TodoListItem key={todo.id} todo={todo} />
))}
</div>
);
};
export default TodoList;
TodoListItem
import React from 'react';
import './TodoListItem.css';
const TodoListItem = ({todo}) => {
const {contents, check} =todo;
return (
<div className="TodoListItem">
<div className="complate"> 완료 </div>
<div className="todo">{contents}</div>
<div className="delete"> 삭제 </div>
</div>
);
};
export default TodoListItem;
먼저 TodoList에서 map을 사용하는 건 불변성 유지를 해줘 야하기 때문이다.
위와 같이 되었다. 이제 TodoInsert에 추가된 내용을 전달받는 함할 수 있게 만들어주기 위해서 App.js에 새로운 함수를 만들어서 전달해주자.
import React, { useState, useCallback, useRef } from 'react';
import './App.css'
import TodoTemplate from './components/TodoTemplate';
import TodoInsert from './components/TodoInsert';
import TodoList from './components/TodoList';
const App = () => {
const [todos, setTodos] = useState([
{
id:1,
contents: '리액트 연습',
check: true
},
{
id:2,
contents: 'todolist',
check: true
},
]);
let nextId = useRef(3);
const insert = useCallback(contents=>{
const todo = {
id:nextId.current,
contents,
check: true
};
setTodos(todos=>todos.concat(todo));
nextId.current += 1;
},[])
return (
<div>
<TodoTemplate >
<TodoInsert insert={insert} />
<TodoList todos={todos}/>
</TodoTemplate>
</div>
);
};
export default App;
여기서 useCallBack()를 사용하는데 이는 필요할 때만 생성할 수 있게 해 준다. 또 useRef()는 지역변수를 만들어줄 수 있는 함수로 사용할 수도 있다.
import React, { useState, useCallback, useRef } from 'react';
import './TodoInsert.css'
const TodoInsert = ({insert}) => {
const [value, setValue] = useState('');
const input = useRef(null);
const onChange = useCallback(e => {
setValue(e.target.value)
});
const onClick = useCallback(e=>{
e.preventDefault();
insert(value);
setValue('');
input.current.focus();
},[insert, value]);
return (
<form className="TodoInsert"
onSubmit={onClick}>
<input
placeholder="내용을 입력하세요"
value={value}
onChange={onChange}
ref={input}
/>
<button>추가</button>
</form>
);
};
export default TodoInsert;
TodoInsert도 위처럼 변경하면 잘 전달되는 것이 보인다. 또 여기서 사용한 useRef로 추가하면 focus 가 자동으로 input으로 가지는 것을 볼 수 있다.
이제 삭제와 완료를 해본다.
//App.js
...
const remove = useCallback(id => {
setTodos(todos.filter(todo=>todo.id !== id))
},[todos]);
const success = useCallback(id => {
setTodos(todos.map(todo => todo.id !== id ? todo : {...todo, check: !todo.check})
)},[todos]);
return (
<div>
<TodoTemplate >
<TodoInsert insert={insert} />
<TodoList todos={todos} remove={remove} success={success}/>
</TodoTemplate>
</div>
);
};
export default App;
삭제와 완료 함수를 정의를 하고 이것을 TodoList의 props로 전달해준다.
import React from "react";
import "./TodoList.css";
import TodoListItem from "./TodoListItem";
const TodoList = ({ todos, remove, success }) => {
return (
<div className="TodoList">
{todos.map(todo => (
<TodoListItem
key={todo.id}
todo={todo}
remove={remove}
success={success}
/>
))}
</div>
);
};
export default TodoList;
다시 TodoListItem에 전달해준다.
import React, { useCallback } from "react";
import "./TodoListItem.css";
const TodoListItem = ({ todo, remove, success }) => {
const { id, contents, check } = todo;
return (
<div className="TodoListItem">
<div className= "complate" onClick={() => success(id)}>
완료
</div>
<div className={check ? "todo success" : "todo" } >{contents}</div>
<div className="delete" onClick={() => remove(id)}>
삭제
</div>
</div>
);
};
export default TodoListItem;
이렇게 다 구현을 해주면 삭제와 완료가 가능해진다. 이제 시작을 하면 전체적으로 가능해진 것을 볼 수 있다.
몇 가지 최적화가 남았지만 기본적인 TodoList는 끝났다.
'프로젝트 > Todo' 카테고리의 다른 글
간단한 TodoList만들기 - (1) (0) | 2020.01.10 |
---|
댓글