Container에 이어서 mobx로 to do app 구현하기를 해봤다.

여러개의 컴포넌트에서 store를 import해서 쓰니까 확실히 사용법을 익히게 되었다.

디렉토리 구조

  1. src > pages > Todo.jsx / Input.jsx / List.jsx : Components 역할
  2. src > stores > todo.js : input과 todoList state 관리하는 store 역할
  3. src > useStore.js : store를 모아서 api처럼 사용하는 역할

todo.js : Store : app과 관련된 상태 input과 list를 같이 관리한다.

import { observable } from 'mobx';

export const todo = observable({
    input: "",
    todoList: [],
    setInput(text) {
        this.input = text;
 //input value 관리
    },
    clearInput() {
        this.input = "";
 //input value 지우기
    },
    add() {
        const temp = { key: Date.now(), what: this.input };
        this.todoList.push(temp);
 //todo object를 생성해서 list에 추가
    },
    remove(id) {
        this.todoList = this.todoList.filter(item => item.key !== id);
st); //삭제할 object를 list에서 제거
    },
    reset() {
        this.todoList.splice(0);
 //list reset
    },
});
  • 더 공부할 것 : array 함수(splice, filter 등)

Todo.jsx : todo list과 input을 보여주는 component

import React from 'react'
import { useObserver } from 'mobx-react'
import useStore from '../useStore'
import Input from './Input'
import List from './List'

const Todo = () => {
    const { todo } = useStore();
    const handleReset = () => {
 todo.reset(); }
    return useObserver(() => (
        <div>
            <Input />
            <ul>
                {todo.todoList.map(item => <List key={item.key} item={item} />)}
            </ul>
            <button onClick={handleReset}>RESET!</button>
        </div>
    )
    );
}

export default Todo
  • map 함수를 통해 list 반복을 할 때 항상 key값을 고유한 값으로 주어야 한다.

List.jsx : 각 todo list component

import React, { memo } from 'react'
import useStore from '../useStore'

const List = memo(({ item }) => {

    const { todo } = useStore();
    const { what } = item;
    const handleRemove = () => {
        todo.remove(item.key);
    };

    return (
        <li>
            <p>{what}</p>
            <button onClick={handleRemove}>I DID IT</button>
        </li>
    )
}
)
export default List
  • 주의할 점 : 부모 컴포넌트에서 그려지는 자식컴포넌트라 해도, STORE를 이용할 경우 useStore를 import 해줘야한다! (useObserver는 NO!)
  • Re-rendering을 막기 위해 memo 사용

Input.jsx : 할 일을 입력하기 위한 Input

import React, { useRef, memo } from 'react'
import { useObserver } from 'mobx-react'
import useStore from '../useStore'

const Input = memo(() => {
    const { todo } = useStore();
    const inputRef = useRef();
    const handleChange = () => {
        todo.setInput(inputRef.current.value);
    }
    const handleClick = (e) => {
        e.preventDefault();
        todo.add();
        todo.clearInput();
        inputRef.current.focus();
    }
    return useObserver(() => (
        <div>
            <input ref={inputRef} type="text" value={todo.input} placeholder="input what you're doing..." onChange={handleChange} />
            <button onClick={handleClick}>I CAN DO IT!</button>
        </div>
   )
);
}
)
export default Input

사실 구현해놓고 보니 input value를 굳이 상태로 관리했어야하나 싶기도 하다. 그래도 뭐 그냥 상태연습으로 치고…

  • useRef를 이용해 input 제어하기(공부더하기)

Leave a comment

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다