본문 바로가기

공부일지/React

비전공자의 공부일지 - Mobx todo앱 만들기

728x90
반응형
반응형

Mobx로 앱만들기

 

Mobx로 간단한 todo 앱을 만드는 프로젝트를 했다.

이번에는 TypeScript로 작업을 진행하였다. 아직 TypeScript에 대해 익숙하지 않아서 내용을 잘못 적을 때도 있다.

 

CRA 할 때 --template typescript 해서 설치하였다.

 

UI 세팅전에 todoStore을 만들었다.

 

todoStore.tsx

import { action, computed, makeObservable, observable } from "mobx";

interface TodoItem {
    id: number;
    title:string;
    completed:boolean
}

export default class TodoStore{
    todos:TodoItem[] = []
    constructor(){
        makeObservable(this, {
            todos: observable,
            addTodo: action,
            toggleTodo: action,
            status: computed
        })
    }
    addTodo(title:string){
        const item: TodoItem = {
            id:getId(),
            title,
            completed:false
        }
        this.todos.push(item);
    }
    toggleTodo(id:number){
        const index = this.todos.findIndex((item) => item.id === id);
        if(index > -1){
            this.todos[index].completed = !this.todos[index].completed;
        }
    }
    get status (){
        let completed = 0, remaining = 0;
        this.todos.forEach((todo)=>{
            if(todo.completed){
                completed++;
            }else{
                remaining++;
            }
        })
        return {completed, remaining}
    }
}

let id = 0
function getId(){
    return id++
}

TodoItem이라는 Interface를 만들어 안에는 id, title, complete에 값을 받을 거라 3가지의 타입도 지정해 주고 todos에 선언해 준다. TodoItem은 배열이기 때문에 당연히 배열로 선언해 주고 빈배열로 시작한다.

todos를 observale로 해주고 addTodo와 toggleTodo, status의 이벤트를 작업했다.

status는 todo에 리스트에서 이벤트를 완료했을 때 1씩 증가한다. 반대로 이벤트 완료 하지 않은 총개수가 remaining의 숫자로 올라간다. 글을 조금 이상하게 작성한 거 같은데 addTodo로 이벤트를 등록하면 리스트가 나오는데 그 리스트에서 내가 해당 일정(리스트)을 완료했을 때 완료 체크를 하면 completed가 1씩 증가하고 일정리스트에서 내가 완료하지 않은 항목의 개수는 remaining가 된다.

 

getId는 addTodo가 실행될때마다 실행되는 함수를 만들었다.

 

App.tsx

import React from 'react';
import './App.css';
import TodoList from './TodoList';
import TodoStore from './TodoStore';

function App() {
	const todoStore = new TodoStore()
	return (
		<div className="App">
			<TodoList todoStore={todoStore} />
		</div>
	);
}

export default App;

todoStore 를 받아오고 그걸 TodoList에 props 값으로 넘겨주었다.

 

todoList.tsx

import React, { useState } from 'react'
import TodoStore from './TodoStore';
import { observer } from 'mobx-react';

interface TodoListProps{
    todoStore:TodoStore;
}

const TodoList: React.FC<TodoListProps> = observer( ({ todoStore }) => {
    const [value, setValue] = useState<string>('')
    return (
        <div>
            <input 
                value={value}
                onChange={event => {
                    setValue(event.target.value)
                }}
            />
            <button
                onClick={()=> {
                    if(value){
                        todoStore.addTodo(value)
                    }
                    setValue('');
                }}
            >
                Add
            </button>
            <div>Completed : {todoStore.status.completed}</div>
            <div>Remaining : {todoStore.status.remaining}</div>
            <ul>
                {todoStore.todos.map((todo)=> {
                    return(
                        <li 
                            key={todo.id} 
                            style={{textAlign:'left'}}
                            onClick={()=>{todoStore.toggleTodo(todo.id)}}
                        >
                            {todo.title} [{todo.completed ? 'x': ' '}]
                        </li>
                    )
                })}
            </ul>
        </div>
    )
})

export default TodoList

button을 클릭하면 addTodo가 실행이 되고 

list로 뿌려주는 방식이다. 

다음에이는 todo리스트를 localStorage에 저장해서 가져오는 걸 만들어야겠다.

 

패스트캠퍼스 프로젝트 중에 하나이다.

프론트엔드 웹개발 모든 것 초격차 패키지 Online의 수업내용 중 하나이다. 

728x90
반응형