티스토리 뷰

3. 스크립트

Velopert Todos 커스텀

패스트코드블로그 2020. 7. 24. 00:07

다음 블로그에서 Todos 부분만 덕패턴으로 편집한 코드입니다.

class 버전과 hooks 버전이 혼합된 부분에서 카운트는 제거하고 투두 부분만

단순 함수형 + 원페이지로 바꿨습니다.

 

https://velopert.com/3533

 

리덕스(Redux)를 왜 쓸까? 그리고 리덕스를 편하게 사용하기 위한 발악 (ii) | VELOPERT.LOG

이 포스트는 이어지는 튜토리얼 입니다. 1편 을 먼저 읽고 오시길 바랍니다. 리덕스의 3가지 규칙 리덕스를 프로젝트에서 사용하게 될 때 알아둬야 할 3가지 규칙이 있습니다. 1. 하나의 애플리케

velopert.com

 

 

index.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import React from 'react';
import ReactDOM from 'react-dom';
import { createStore, combineReducers } from 'redux';
import { Provider } from 'react-redux';
import { todosReducer } from "./VelopTodos";
import App from './VelopTodos';
const rootReducer = combineReducers({
        todosReducer
})
ReactDOM.render(
    <Provider store={createStore(rootReducer)}><App /></Provider>,
    document.getElementById('root'),
);
 
 
cs

 

VelopTodos.js

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
import {useSelector} from 'react-redux'
import React, { useMemo } from "react";
import { bindActionCreators } from "redux";
import { useDispatch } from "react-redux";
import {createAction, handleActions} from 'redux-actions'
import produce from 'immer'
 
const CHANGE_INPUT = 'todos/CHANGE_INPUT'
const INSERT = 'todos/INSERT'
const TOGGLE = 'todos/TOGGLE'
const REMOVE = 'todos/REMOVE'
 
const changeInput = createAction(CHANGE_INPUT, input => input)
let id = 3
const insert = createAction(INSERT, text => ({id: id++text, done: false}))
const toggle = createAction(TOGGLE, id => id)
const remove = createAction(REMOVE, id => id)
 
const initailState = {
    input: '',
    todos: [
        {
            id: 1,
            text'리액트 학습',
            done: true
        },
        {
            id: 2,
            text'리덕스 학습',
            done: false
        }
    ]
}
 
export const todosReducer = handleActions({
    [CHANGE_INPUT]: (state, {payload: input})=> produce(state, draft =>{draft.input = input}) ,
    [INSERT]: (state, {payload: todo})=> produce(state, draft => {draft.todos.push(todo)}),
    [TOGGLE]: (state, {payload: id})=>
        produce(state, draft => {const todo = draft.todos.find(todo => todo.id === id)
            todo.done = !todo.done}),
    [REMOVE]: (state, { payload: id })=>
        produce(state, draft => {const index = draft.todos.findIndex(todo => todo.id === id)
            draft.todos.splice(index, 1)})
 
}, initailState)
 
 
 
const useActions = (actions, deps) => {
    const dispatch = useDispatch()
    return useMemo(
        ()=>{
            if(Array.isArray(actions)){
                return actions.map(a => bindActionCreators(a, dispatch))
            }
            return bindActionCreators(actions, dispatch)
        }, deps ? [dispatch, ...deps] : deps
    )
}
 
const TodoItem = ({todo, onToggle, onRemove}) =>{
    return <>
        <div>
            <input
                type="checkbox"
                onClick={() => onToggle(todo.id)}
                checked={todo.done}
                readOnly={true}
            />
            <span style={{ textDecoration: todo.done ? 'line-through' : 'none' }}>
                {todo.text}
              </span>
            <button onClick={() => onRemove(todo.id)}>삭제</button>
        </div>
    </>
}
 
 
const Todos= ({input, todos, onChangeInput, onInsert,  onToggle, onRemove}) => {
    const onSubmit = e => {
        e.preventDefault()
        onInsert(input)
        onChangeInput('')
    }
    const onChange = e => {
        e.preventDefault()
        onChangeInput(e.target.value)
    }
    return <>
        <div>
            <form onSubmit={onSubmit} >
                <div>
                    <div >
                        <input
                            value={input}
                            onChange={onChange}
                        />
                    </div>
                    <button type="submit">
                        등록
                    </button>
                </div>
            </form>
            <div>
                {
                    todos.map(todo=>(<TodoItem
                        todo={todo}
                        key={todo.id}
                        onToggle={onToggle}
                        onRemove={onRemove}/>))
                }
            </div>
        </div>
    </>
}
 
const TodosApp = () => {
    const {input, todos} =
        useSelector(({todosReducer})=>({input: todosReducer.input, todos: todosReducer.todos}))
    const [onChangeInput, onInsert, onToggle, onRemove] = useActions(
        [changeInput, insert, toggle, remove],
        [])
    return (
        <Todos input={input} todos={todos} onChangeInput={onChangeInput}
                    onInsert={onInsert} onToggle={onToggle} onRemove={onRemove}/>)
}
export default React.memo(TodosApp)
cs

 

댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2025/01   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함