#3 To-Do 앱 최적화 하기 - 4

김민성·2023년 5월 2일
0
post-thumbnail

TailWindCSS에 대해서

TailWindCSS란 무엇인가?

HTML 안에서, CSS 스타일을 만들 수 있게 해주는 CSS 프레임 워크이다.

CSS 프레임 워크는 무엇인가?

CSS 프레임워크는 레이아웃 및 여러 컴포넌트 구성, 브라우저 호환성을 보장하는데 소요되는 시간을 최소화하기 위해 여러 웹 개발/디자인 프로젝트에 적용할 수 있는 CSS 파일 모음이다.

CSS FRAMEWORK 종류 for React JS

  1. Material UI
    2.React Bootstrap
    3.Semantic UI
    4.Ant Design
  2. Materialize

Tailwind CSS의 장점

Tailwind CSS는 부트스트랩과 비슷하게 m-1, flex와 같이 미리 세팅된 Uitility Class 를 활용하는 방식으로 HTML 에서 스타일링을 할 수 있다.
1. 빠른 스타일링 작업이 가능
2. class 혹은 id 명을 작성하기 위한 고생을 하지 않아도 된다.
3. 유틸리티 클래스가 익숙해지는 시간이 필요할 수 있지만 IntelliSense 플러그인이 제공돼서 금방 익숙해질 수 있다.

https://tailwindcss.com/docs/installation/using-postcss
위 링크에서 설치 방법을 따라가면 된다.

TailWindCss로 Todo 앱 스타일링 해주기

원래 스타일링 지우기

스타일링을 모두 지운 후의 코드는 다음과 같다.
App.css

import React from 'react'

export default function List({todoData, setTodoData}) {

const btnStyle = {
    color: "#fff",
    border: "none",
    padding: "5px 9px",
    borderRadius: "50%",
    cursor: "pointer",
    float: "right"
}

const getStyle = (completed) => {
    return {
        padding: "10px",
        borderBottom: "1px #ccc dotted",
        textDecoration: completed ?"line-through" :"none"
    }
}

const handleClick = (id) => {
    let newTodoData = todoData.filter(data => data.id !== id);
    console.log('newTodoData', newTodoData);
    setTodoData(newTodoData)
}

const handleCompleteChange = (id) => {
    let newTodoData = todoData.map(data => {
        if(data.id === id) {
            data.completed = !data.completed; // 반대로
        }
        return data;
    })
    setTodoData(newTodoData);
}


    return (
        <div>
            {todoData.map((data) => (
            <div key={data.id}>
            <input type="checkbox" 
            defaultChecked={false} 
            onChange={() => handleCompleteChange(data.id)} />
            {data.title}
            <button onClick={() => handleClick(data.id)}>x</button>
            </div>
            ))}
        </div>
    )
}

App.js

import React, {useState} from "react"; //react는 라이브러리이므로 컴포넌트를 가져와서 
import "./App.css"
import List from "./components/List";
import Form from "./components/Form";

export default function App() {

  const [todoData, setTodoData] = useState([]);
  const [value, setValue] = useState("");

  

  const handleSubmit = (e) => {
    e.preventDefault(); //페이지가 리로드 되는 것을 막아줌.

    //새로운 할 일 데이터
    let newTodo = {
      id: Date.now(),
      title: value,
      completed: false
    }

    //원래 있던 할 일에 새로운 할 일 더해주기
    setTodoData(prev => [...prev, newTodo]);
    setValue("");

  }

    return(
      <div >
        <div>
          <div>
            <h1>할 일 목록</h1>
          </div>

          <List todoData={todoData} setTodoData={setTodoData} />

          <Form handleSubmit={handleSubmit} value={value} setValue={setValue} />

        </div>
      </div>
    )
  }

Form.js

import React from 'react'

export default function Form({handleSubmit, value, setValue}) {

    const handleChange = (e) => {
        setValue(e.target.value)
    };

    return (
        <form onSubmit={handleSubmit}>
        <input 
        type='text' 
        name="value" 
        placeholder="해야 할 일을 입력하세요." 
        value={value}
        onChange={handleChange}
        />
    <input 
        type="submit"
        value="입력"
    />

    </form>
    )
}

List.js

import React from 'react'

export default function List({todoData, setTodoData}) {

const handleClick = (id) => {
    let newTodoData = todoData.filter(data => data.id !== id);
    console.log('newTodoData', newTodoData);
    setTodoData(newTodoData)
}

const handleCompleteChange = (id) => {
    let newTodoData = todoData.map(data => {
        if(data.id === id) {
            data.completed = !data.completed; // 반대로
        }
        return data;
    })
    setTodoData(newTodoData);
}


    return (
        <div>
            {todoData.map((data) => (
            <div key={data.id}>
            <input type="checkbox" 
            defaultChecked={false} 
            onChange={() => handleCompleteChange(data.id)} />
            {data.title}
            <button onClick={() => handleClick(data.id)}>x</button>
            </div>
            ))}
        </div>
    )
}

바꾸게 될 UI

tailwind를 활용해 스타일링을 적용하자. 코드를 다음과 같이 바꿔주면 된다.

App.js

import React, {useState} from "react"; //react는 라이브러리이므로 컴포넌트를 가져와서 
import "./App.css"
import List from "../../new-react-project/src/components/List";
import Form from "../../new-react-project/src/components/Form";

export default function App() {

  const [todoData, setTodoData] = useState([]);
  const [value, setValue] = useState("");

  

  const handleSubmit = (e) => {
    e.preventDefault(); //페이지가 리로드 되는 것을 막아줌.

    //새로운 할 일 데이터
    let newTodo = {
      id: Date.now(),
      title: value,
      completed: false
    }

    //원래 있던 할 일에 새로운 할 일 더해주기
    setTodoData(prev => [...prev, newTodo]);
    setValue("");

  }

    return(
      <div className="flex items-center justify-center first-letter:w-screen h-screen bg-blue-100" >
        <div className = "w-full p-6 m-4 bg-white rounded shadow lg:w-3/4 md:max-w-lg lg:W-3/4 lg:max-w-lg">
          <div className="flex justify-between mb-3">
            <h1>할 일 목록</h1>
          </div>

          <List todoData={todoData} setTodoData={setTodoData} />

          <Form handleSubmit={handleSubmit} value={value} setValue={setValue} />

        </div>
      </div>
    )
  }

Form.js

import React from 'react'

export default function Form({handleSubmit, value, setValue}) {

    const handleChange = (e) => {
        setValue(e.target.value)
    };

    return (
        <form onSubmit={handleSubmit} className="flex pt-2">
        <input 
        type='text' 
        name="value" 
        className='w-full px-3 py-2 mr-4 text-gray-500 border rounded shadow'
        placeholder="해야 할 일을 입력하세요." 
        value={value}
        onChange={handleChange}
        />
    <input className='p-2 text-blue-400 border-2 border-blue-400 rounded hover:text-white hover:bg-blue-200'
        type="submit"
        value="입력"
    />

    </form>
    )
}

List.js

import React from 'react'

export default function List({todoData, setTodoData}) {

const handleClick = (id) => {
    let newTodoData = todoData.filter(data => data.id !== id);
    console.log('newTodoData', newTodoData);
    setTodoData(newTodoData)
}

const handleCompleteChange = (id) => {
    let newTodoData = todoData.map(data => {
        if(data.id === id) {
            data.completed = !data.completed; // 반대로
        }
        return data;
    })
    setTodoData(newTodoData);
}


    return (
        <div>
            {todoData.map((data) => (
            <div key={data.id}>
                <div className='flex items-center justify-between w-full px-4 py-1 my-2 text-gray-600 bg-gray-100 border rounded'>
                    <div className='items-center'>
                        
                        <input type="checkbox" 
                        defaultChecked={data.completed} 
                        onChange={() => handleCompleteChange(data.id)} 
                        />{" "}
                        <span className={data.completed && "line-through"}>{data.title}</span>

                    </div>
                    <div>
                        <button className="px-4 py-2 float-right" onClick={() => handleClick(data.id)}>x</button>
                    </div>
                </div>
            </div>
            ))}
        </div>
    )
}

위와 같이 바꿔주면 다음과 같은 결과를 볼 수 있다.

profile
다양한 활동을 통해 인사이트를 얻는 것을 즐깁니다. 저 또한 인사이트를 주는 사람이 되고자 합니다.

0개의 댓글

관련 채용 정보