React로 Todo 만들기

2024. 1. 15. 22:19React 정리

728x90

빈 폴더를 하나 만들고

터미널을 열고

npm create vite@latest
√ Project name: . or 생성할 폴더명(본인이름)
√ Package name: movie-app
√ Select a framework: » React
√ Select a variant: » JavaScript

  npm install 
  npm run dev

 

# 스타일 컴포넌트
npm install styled-components
# 라우터
npm install react-router-dom

 

 

 

 

src 폴더에 App.jsx, main.jsx 말고는 다 삭제하고 남겨준다.

 

 

 

 

 

 

 

 

 

App.jsx 는 옆에 저 코드가 시작코드이다.

다 삭제하고 저렇게 만들어준다.

 

 

 

 

 

 

 

 

main.jsx 코드이다.

 

 

 

 

 

 

 

또 리액트는 컴포넌트로 분리시켜 유지보수와 편리성을 더해준다.

 

전체 코드

App.jsx

import { useRef, useState } from "react"
import TodoInsert from "./components/TodoInsert"
import TodoList from "./components/TodoList"
import TodoTemplate from "./components/TodoTemplate"

function App() {

  return (
    <TodoTemplate>
      <TodoInsert />
      <TodoList />
    </TodoTemplate>
  )
}

export default App

 

 Components

#TodoInsert

import { useState } from "react";

function TodoInsert() {
  const [text, setText] = useState("");

  const onInsert = (text) => {
    fetch(`https://todo20240118-1.fly.dev/api/v1/todos`, {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
      },
      body: JSON.stringify({
        content: text,
      }),
    });
  };

  const onChange = (e) => {
    console.log(e.target.value);
    setText(e.target.value);
  };

  const onSubmit = (e) => {
    onInsert(text);
    setText("");
    e.preventDefault();
  };

  return (
    <div>
      <form onSubmit={onSubmit}>
        <input
          placeholder="할 일을 입력하세요."
          type="text"
          value={text}
          onChange={onChange}
        />
        <button type="submit">저장</button>
      </form>
    </div>
  );
}

export default TodoInsert;

 

# TodoList

import { useEffect, useState } from "react";
import TodoListItem from "./TodoListItem";

function TodoList() {
  const [todos, setTodos] = useState([]);

  useEffect(() => {
    fetch("https://todo20240118-1.fly.dev/api/v1/todos")
      .then((res) => res.json())
      .then((result) => setTodos(result.data));
  }, [todos]);

  return (
    <div>
      {todos && todos.map((todo) => <TodoListItem key={todo.id} todo={todo} />)}
    </div>
  );
}

export default TodoList;
# TodoListItem
function TodoListItem({ todo }) {
  const { id, content, is_checked } = todo;

  const onDelete = () => {
    fetch(`https://todo20240118-1.fly.dev/api/v1/todos/${id}`, {
      method: "DELETE",
    });
  };

  const onToggle = () => {
    fetch(`https://todo20240118-1.fly.dev/api/v1/todos/${id}`, {
      method: "PATCH",
      headers: {
        "Content-Type": "application/json",
      },
      body: JSON.stringify({
        is_checked: !is_checked,
      }),
    });
  };

  return (
    <div style={{ textDecoration: is_checked ? "line-through" : "none" }}>
      <input
        type="checkbox"
        checked={is_checked}
        onChange={() => onToggle(id)}
      />
      {id}
      <span>번 : {content}</span>
      <button onClick={() => onDelete(id)}>삭제</button>
    </div>
  );
}

export default TodoListItem;
#TodoTemplet
function TodoTemplate({children}) {
    return (
        <> 
            <h1>TODO-APP 만들기</h1>
            <div>{children}</div> 
        </>
    );
}

export default TodoTemplate;