Redux 기초-2 (TODO)

CCY·2020년 6월 25일
0

Redux

목록 보기
5/8
post-thumbnail

TODO COMPONENT 만들기

import React from "react"

const TodoItem = ({ todo, onToggle, onRemove }) => {
  return (
    <div>
      <input type="checkbox" />
      <span>예제 테스트</span>
      <button>삭제</button>
    </div>
  )
}

const Todos = ({
  input, //인풋에 입력되는 테스트
  todos, //할일 목록 들어 있는 객체
  onChangeInput,
  onInsert,
  onToggle,
  onRemove,
}) => {
  const onSubmit = (e) => {
    e.preventDefault()
  }
  return (
    <div>
      <form onSubmit={onSubmit}>
        <input />
        <button type="submit">등록</button>
      </form>
      <TodoItem />
      <TodoItem />
      <TodoItem />
      <TodoItem />
    </div>
  )
}

export default Todos

REDUX 적용하기 (ACTION~REDUCER)

modules/todo.js

//Action Type
const CHANGE_INPUT = "todos/CHANGE_INPUT" //인풋 값을 변경함
const INSERT = "todos/INSERT" //새로운 todos를 등록함
const TOGGLE = "todos/TOGGLE" // todo를 체크 /체크 해체함
const REMOVE = "todos/REMOVE" //todos 제거함

//Action Function

export const changeInput = (input) => ({
  type: CHANGE_INPUT,
  input,
})

let id = 3
export const insert = (text) => ({
  type: INSERT,
  todo: {
    id: id++,
    text,
    done: false,
  },
})

export const toggle = (id) => ({
  type: TOGGLE,
  id,
})

export const remove = (id) => ({
  type: REMOVE,
  id,
})

//REDUCER

const initialState = {
  input: "",
  todos: [
    {
      id: 1,
      text: "리덕스 기초 배우기",
      done: true,
    },
    {
      id: 2,
      text: "리덕스 기초 배우기",
      done: false,
    },
  ],
}

function todos(state = initialState, action) {
  switch (action.type) {
    case CHANGE_INPUT:
      return {
        ...state,
        input: action.input,
      }
    case INSERT:
      return {
        ...state,
        todos: state.todos.concat(action.todo),
      }
    case TOGGLE:
      return {
        ...state,
        todos: state.todos.map((todo) =>
          todo.id === action.id ? { ...todo, done: !todo.done } : todo
        ),
      }
    case REMOVE:
      return {
        ...state,
        todos: state.todos.filter((todo) => todo.id !== action.id),
      }
    default:
      return state
  }
}

export default todos

modules/index.js

COMBINE REDUCER

import { combineReducers } from "redux"
//import addList from "./addList"
import todos from "./todos"

const rootReducer = combineReducers({
  todos,
})

export default rootReducer

REDUX TODO COMPONENT 액션 담당하기 위한 CONTAINER 만들기

containers/TodosContainer.js

import React from "react"
import { connect } from "react-redux"
import { changeInput, insert, toggle, remove } from "../modules/todos"
import Todos from "../components/Todos"

const TodosContainer = ({ input, todos, changeInput, insert, toggle, remove }) => {
  return (
    <Todos
      input={input}
      todos={todos}
      onChangeInput={changeInput}
      onInsert={insert}
      onToggle={toggle}
      onRemove={remove}
    />
  )
}

export default connect(
  //비구조화 할당을 통해 todos를 분리하여
  //state.todos.input 대신 todos.input 사용
  ({ todos }) => ({
    input: todos.input,
    todos: todos.todos,
  }),
  {
    changeInput,
    insert,
    toggle,
    remove,
  }
)(TodosContainer)

REDUX 애플리케이션에 적용하기

import React from "react"
import ReactDOM from "react-dom"
import { createStore } from "redux"
import { Provider } from "react-redux"
import rootReducer from "../src/Redux/modules"
import { composeWithDevTools } from "redux-devtools-extension"
import TodosContainer from './containers.TodosContainer

const store = createStore(rootReducer,composeWithDevTools())

ReactDOM.render(
  <React.StrictMode>
    <Provider store={store}>
      <TodosContainer />
    </Provider>
  </React.StrictMode>,
  document.getElementById("root")
)

Todos 컴포넌트에서 받아온 props를 사용하도록 구현하기

components/Todos.js

import React from "react"

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("") //등록 후 input 초기화
  }
  const onChange = (e) => onChangeInput(e.target.value)
  return (
    <div>
      <form onSubmit={onSubmit}>
        <input value={input} onChange={onChange} />
        <button type="submit">등록</button>
      </form>
      <div>
        {todos.map((todo) => (
          <TodoItem todo={todo} key={todo.id} onToggle={onToggle} onRemove={onRemove} />
        ))}
      </div>
    </div>
  )
}

export default Todos

profile
✍️ 기록을 습관화 하자 ✍️ 나는 할 수 있다, 나는 개발자가 될거다 💪🙌😎

0개의 댓글