TS+REACT+TailwindCSS로 Todo 구현해보기(1)

hatban·2023년 4월 5일
0

타입스크립트로 제로웨이브를 다시 만들어야하는데
막상 만들려고하니까 조금 혼란스럽기도해서 미니 실습은 하나라도 혼자 해보고 진행하기로 했다..!!

투두리스트는 그동안 자바스크립트로도 해보고 리액트로도 발전시켜봤는데 또 하는게 맞나..싶었지만
이만큼 금방 만들고 쉽게 적용할 수 있는 실습이 우선 생각이 안나서 뭐라도 해본다..!



우선 내가 정의한 기능은 이렇다
예전에는 그냥 무작정 코드를 작성부터 했는데 이렇게 정의하고
정의한 내용을 보고 하면 좀 효율성이 높아지는 것 같기도 ~_~

그리고 세운 할 일 목록들!

++ Tailwindcss도 사용해보고 싶었기 때문에 적용해보려고 한다



Figma로 만든 초기 구상



Tailwind CSS초기 세팅

  1. npm 파일들 설치
$ npm install -D tailwindcss@latest
$ npm install -D postcss@latest 
$ npm install -D autoprefixer@latest
$ npm install -D postcss-loader
  1. postcss.config.js 생성
// postcss.config.js
module.exports = {
  plugins: {
    tailwindcss: {},
    autoprefixer: {},
  },
};
  1. tailwind.config.js 생성
// tailwind.config.js
module.exports = {
  purge: ["./src/**/*.{js,jsx,ts,tsx}", "./public/index.html"],
  content: [],
  darkMode: false, // or 'media' or 'class'
  theme: {
    extend: {},
  },
  variants: {
    extend: {},
  },
  plugins: [],
};

직접 위와 같이 만들어주거나

npx tailwindcss-cli@latest init

로 생성 할 수 있다.

  1. webpack.confing.js 생성

    자바스크립트 파일들을 하나의 자바스크립트 파일로 만들기 위함

// webpack.config.js
module: {
    rules: [
      {
        test: /.jsx?$/,
        include: [path.resolve(__dirname, "src")],
        exclude: [path.resolve(__dirname, "node_modules")],
        loader: "babel-loader",
      },
      {
        test: /.css?$/,
        exclude: [],
        //로더는 오른쪽부터 읽어들이므로 postcss-loader를 맨 오른쪽에 넣어준다.
        use: ["style-loader", "css-loader", "postcss-loader"],
      },
    ],
  },
  1. index.css 설정
// index.css 
@import "tailwindcss/base";
@import "tailwindcss/components";
@import "tailwindcss/utilities";
  1. index.tsx에 index.css 연결

생각보다.. 해야할게 많구나..!


UI구성

// App.tsx
import React from 'react';
import TodoList from './components/TodoList';
import TodoInput from './components/TodoInput';
import TodoStateBtns from './components/TodoStateBtns';

function App() {
  return (
    <div className="App flex flex-col items-center font-mono">
      <h1 className="text-xl font-semibold mt-9">Todo List</h1>
      <div>
        <TodoInput />
        <TodoStateBtns />
        <TodoList />
      </div>
    </div>
  );
}

export default App;

TodoInput, TodoStateBtns, TodoList로 컴포넌트를 구분했다.

결과

tailwind Css를 이용해서 스타일을 적용한 결과


Todo 추가하는 Event구현

상위 컴포넌트에 todoinput과 list컴포넌트가 하위 컴포넌트로 있어서 이걸
input -> 상위 -> list 이렇게 전달하는게 번거로울것 같아서 리덕스를 사용했다

  • Redux라는 폴더에 Actions와 Reducers 폴더로 하위 폴더를 구분하고 전체 action type은 types.ts에 정의했다
// types.ts

export const ADD_TODO = 'todo/addtodo' as const;
export const DELETE_TODO = 'todo/deletetodo' as const;
export const CHECK_TODO = 'todo/checktodo' as const;
export const GET_TODO = 'todo/gettodo' as const;
//todolist_action.ts
import { ADD_TODO, DELETE_TODO, CHECK_TODO, GET_TODO } from '../types';

export function addTodo(todoID: string, todoContent: string, checked: boolean) {
  return {
    type: ADD_TODO,
    payload: {
      todoID,
      todoContent,
      checked,
    },
  };
}

...
// todoReducer.ts
import { ADD_TODO, DELETE_TODO, CHECK_TODO, GET_TODO } from '../types';
import {
  addTodo,
  deleteTodo,
  checkTodo,
  getTodo,
} from '../Actions/todolist_action';

interface Todo {
  todoID: string;
  todoContent: string;
  checked: boolean;
}

type TodoListStateType = Todo[];

const initialState: TodoListStateType = [];

type TodoActionType =
  | ReturnType<typeof addTodo>
  | ReturnType<typeof deleteTodo>
  | ReturnType<typeof checkTodo>
  | ReturnType<typeof getTodo>;

export default function todoReducer(
  state: TodoListStateType = initialState,
  action: TodoActionType
) {
  switch (action.type) {
    case ADD_TODO:
      console.log('페이로드 : ', action.payload);
      return {};
    case DELETE_TODO:
      return {};
    case CHECK_TODO:
      return {};
    case GET_TODO:
      return {};
    default:
      return state;
  }
}

결과

  • 정상적으로 디스패치가 액션을 호출하는 것을 확인할 수 있었다!

후기

  • 아직 진행해야 할 부분이 많다!
  • 우선 타입스크립트는 아직 본격적으로 사용해보지 않은 것 같아서 추후 로직을 짜다보면
    더 사용하지 않을까 싶고, tailwind로 하니 css 파일을 만들지 않아도 되서 편리했다
  • 그런데 css가 없는대신 classname이 길어지는 것 같아서 무엇이 장점인지 나에게 더 편한지 고민해봐야겠다.

0개의 댓글