개요
모던 자바스크립트의 구조를 학습하고 컴포넌트 기반의 코드를 작성한다.
목표
순수 Javascript로 작성된 Todo List 어플리케이션을 작성한다.
(이 글은 Next Step에서 진행한 js-todo-list-step을 따라 작성되었습니다.)
전체 코드는 여기에서 보실 수 있습니다.
여정
들어갈 자리 확인하기
기존에 작성되어 있던 index.html에서 TodoList의 자리를 한번 확인해보자.
<section class="todoapp">
<section class="input-container">
...
</section>
<section class="main">
...
</section>
<div class="count-container">
...
</div>
</section>
위와 같이 크게 3가지 항목으로 구성되어 있다.
우리는 이 부분을 각각 컴포넌트로 작성할 것이다.
먼저, 기본 기능인 2가지 컴포넌트를 먼저 작성해보도록 하자.
- Todo를 생성해주는 Todo Input
- 목록을 보여주는 Todo List
일단 먼저, html에서 section 태그만 남기고 정리해주자
그리고, 쉽게 찾을 수 있게 id를 태그 안에 넣어주자
<section class="todoapp">
<section class="input-container" id="todo-input"></section>
<section class="main" id="todo-list"></section>
<div class="count-container" id="todo-count"></div>
</section>
App.js에서 호출하면 아래와 같은 모양이 된다.
이제 TodoList와 TodoInput 컴포넌트를 같이 작성해보자
import { $ } from "./utils/selector.js";
import { UserList, TodoList, TodoInput } from "./component/index.js";
export default class TodoApp {
constructor($target) {
this.$target = $target;
this.setup();
}
setup () {
const userListTarget =$('#user-list');
const todoListTarget =$('#todo-list');
const todoInputTarget =$('#todo-input');
new UserList(userListTarget);
new TodoList(todoListTarget);
new TodoInput(todoInputTarget);
}
}
Todo List
User Component 때를 생각하면, 단순 목록만 보여주는 일은 굉장히 단순하다.
Todo Item 1개의 모양을 잡고, 리스트 형태로 보여주면 된다.
Todo Item은 현재 3가지 정보만 있으면 충분할 것으로 보인다.
- ID : Todo item을 구분하기 위함 (현재 시각에 따라 생성)
- Content : Todo item의 내용
- Completed : 완료 여부(생성 시에는 무조건 false)
이를 코드로 구현하면 바로 아래와 같은 모양이 될 것이다.
// TodoList.js
import Component from "../core/Component.js";
import {store} from "../store/index.js";
const TodoItem = (todo) => {
const { id, content, completed } = todo;
return `
<li data-id="${id}">
<div class="view">
<input class="toggle" type="checkbox" ${completed ? 'checked' : ''} />
<label class="label">
${content}
</label>
<button class="destroy"></button>
</div>
</li>
`;
}
export default class TodoList extends Component {
initState () { return {}; }
mounted () {
// 컴포넌트가 마운트된 후에 동작한다.
}
template () {
const { todos } = store.getState();
// 컴포넌트의 내용을 반환
// join을 하지 않으면 ','까지 같이 출력된다
return `
<ul class="todo-list">
${ todos && todos.map((todo) => TodoItem(todo)).join('')}
</ul>
`
}
setEvent () {
}
}
Todo List 목록조회는 이게 끝이다.
간단하지 않은가?
(물론 추후 기능이 굉장히 많다!!)
바로 다음으로 넘어가보자
Todo Input
Todo Input의 역할은 간단하다.
Input 태그의 모양을 생성해주고, 엔터 이벤트를 받아 Todo Item 저장 요청을 해주면 된다.(그려주는 일에 대한 책임은 가지고 있지 않다.)
바로 아래와 같은 모양새가 될 것이다.
import Component from "../core/Component.js";
import { store } from "../store/index.js";
import { createTodo } from "../store/todo/creator.js";
export default class TodoInput extends Component {
initState() {
return {};
}
mounted() {
// 컴포넌트가 마운트된 후에 동작한다.
}
template() {
return `
<input
class="new-todo"
placeholder="할 일을 입력해주세요."
autofocus
/>
`;
}
setEvent() {
this.enterTodoItem();
}
enterTodoItem() {
this.addEvent("keydown", ".new-todo", (event) => {
const content = event.target.value;
if (event.key === "Enter" && content) {
this.createTodoItem(content);
event.target.value = "";
}
});
}
createTodoItem(content) {
store.dispatch(createTodo(content));
}
}
Enter 이벤트가 발생했을 때, createTodoItem을 호출하고 있다.
reducer에 이벤트 타겟의 내용물(todo의 내용)을 전달한다.
여기서 reducer 함수인 createTodo의 모양을 한번 보도록 하자.
// todo/creator.js
const createTodo = (content) => {
return {
type: CREATE_TODO,
payload: {
id: String(Date.now()),
content: content,
completed: false
},
}
}
전달받은 것은 내용물 content 뿐이지만,
실제 store에 저장하는 것은 3가지다. (ID, Content, Completed)
reducer는 store에 todoItem을 전달하므로
이를 저장할 리스트와 그에 맞는 연산을 만들어주자.
(User 컴포넌트를 작성했을 때와 마찬가지)
// reducer.js
let initialState = {
users: [],
todos: [], // 추가
}
const reducer = (state = initialState, action = {}) => {
...
case CREATE_TODO:
return {
...state,
todos: [...state.todos, action.payload],
}
...
}
자, 이제 Todo Item을 생성하는 일을 할 수 있게 되었다.
Todo Input에 내용을 적고 엔터를 누르면 목록에 추가되는 것을 볼 수 있다.
마무리
여기까지가 기본 컴포넌트의 뼈대 기능만 빠르게 작성해보았다.
다음 시간에는 TodoList의 삭제, 편집 기능을 추가해보도록 하자.
참고자료
'Frontend' 카테고리의 다른 글
모던 자바스크립트 TodoList - Todo Component (3) (0) | 2023.05.08 |
---|---|
모던 자바스크립트 TodoList - Todo Component (2) (0) | 2023.05.06 |
모던 자바스크립트 TodoList - User Component (0) | 2023.04.21 |
모던 자바스크립트 TodoList - Store & Reducer (0) | 2023.04.17 |
모던 자바스크립트 TodoList - Component & Observer (0) | 2023.04.16 |