Notice
Recent Posts
Recent Comments
Link
«   2024/09   »
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
Tags
more
Archives
Today
Total
관리 메뉴

훈돌라

2024. 5. 29. 리액트 베이직 useState 응용 (회원가입, TodoList) 본문

카테고리 없음

2024. 5. 29. 리액트 베이직 useState 응용 (회원가입, TodoList)

훈돌라 2024. 5. 29. 18:06
import { useState } from "react";

function App() {
  const [email, setEmail] = useState("");

  const handleEmailChange = (event) => {
    setEmail(event.target.value);
  };

  const [password, setPassword] = useState("");

  const handlePasswordChange = (event) => {
    setPassword(event.target.value);
  };

  const [passwordcheck, setPasswordCheck] = useState("");

  const PasswordCheckChange = (event) => {
    setPasswordCheck(event.target.value);
  };

  const onSubmit = (event) => {
    event.preventDefulat();
    if (!email) {
      alert("이메일을 입력하세요");
      return; // 리턴이 없으면 밑 alert 까지 실행됨 return 으로 여기서 끝냄
    }

    if (password.length < 8) {
      alert("비밀번호를 입력하세요");
      return;
    }

    if (password !== passwordcheck) {
      alert("비밀번호와 비밀번호 확인이 일치하지 않습니다.");
      return;
    }
    alert(`이메일은${email}이고 비밀번호는 ${password}`);
  };

  return (
    <form onSubmit={onSubmit}>
      <div>
        <label htmlFor="email">이메일:</label>
        <input
          type="email"
          id="email"
          value={email}
          onChange={handleEmailChange}
        />
      </div>
      <div>
        <label htmlFor="password">비밀번호:</label>
        <input
          type="password"
          id="password"
          value={password}
          onChange={handlePasswordChange}
        />
      </div>
      <div>
        <label htmlFor="passwordConfirm">비밀번호 확인:</label>
        <input
          type="password"
          id="passwordConfirm"
          value={passwordcheck}
          onChange={PasswordCheckChange}
        />
      </div>
      <button type="submit">회원가입</button>
    </form>
  );
}

export default App;

 

회원가입 및 유효성 검사

 

import "./App.css";
import React, { useState } from "react";

const App = () => {
  const [input, setInput] = useState("");
  const [todos, setTodo] = useState([
    {
      id: 1,
      text: "잠자기",
      completed: true,
    },
    {
      id: 2,
      text: "일찍 일어나기",
      completed: false,
    },
  ]);

  // useState 에 전달된 배열->객체가 초기상태로 설정됨 setTodo 함수를 이용해 상태를 업데이트 할 수 있음

  const handleInputChange = (event) => {
    setInput(event.target.value);
  };
  // event.target 은 이벤트가 발생한 인풋을 가르킴, value 는 인풋의 현재 값 (내가 입력한 값이 인풋 상태에 저장됨)

  const handleAddTodo = (event) => {
    event.preventDefault(); // 이벤트의 기본 동작(폼 제출 시 페이지 새로고침)을 막음
    if (!input.trim()) return; // 입력된 값(input)이 공백 문자만으로 이루어져 있는지 확인,
    //공백 문자만 있을 경우 함수는 아무 작업도 하지 않고 종료. input.trim()은 문자열의 앞뒤 공백을 제거한 결과를 반환.

    const newTodo = {
      id: Date.now(), //현재 시간을 나타내는 Date.now() 값을 사용하여 고유한 id를 생성
      text: input, // 입력된 값(input)을 할 일의 텍스트로 설정.
      completed: false, //새로운 할 일은 기본적으로 완료되지 않은 상태(false)로 설정.
    };
    setTodo([...todos, newTodo]); //현재의 todos 배열에 newTodo 객체를 추가하여 새로운 배열을 생성, 새로운 할 일이 기존 할 일 목록에 추가됨.
    setInput(""); // 인풋 초기화 빈 문자열 설정.
  };

  const handleDeleteTodo = (id) => {
    setTodo(todos.filter((todo) => todo.id !== id));
  };
  //todos 배열을 순회하면서 각 todo 객체의 id가 삭제하려는 id와 일치하지 않는 객체들만을 포함하는 새로운 배열을 만듬
  //해당 id를 가진 할 일을 제외한 나머지 할 일들로 새로운 배열 만듬

  const handleToggleTodo = (id) => {
    setTodo(
      todos.map((todo) =>
        todo.id === id ? { ...todo, completed: !todo.completed } : todo
      )
    );
  };
  //todos 배열을 순회 ->  현재 순회 중인 todo 객체의 id가 주어진 id와 같다면, 해당 todo 객체의 completed 속성을 반전시킴
  //객체 전개 연산자(...todo)를 사용하여 기존 todo 객체의 모든 속성을 복사한 뒤 completed 속성만 업데이트함

  return (
    <div>
      <h1>할 일 목록</h1>
      <form onSubmit={handleAddTodo}>
        <input
          type="text"
          placeholder="할 일을 추가하세요"
          value={input}
          onChange={handleInputChange}
        />
        <button type="submit">추가</button>
      </form>
      <ul>
        {todos.map((todo) => (
          <li
            key={todo.id}
            style={{ textDecoration: todo.completed ? "line-through" : "none" }} // todo.completed 가 true 일 경우 line-through, false 인 경우 none
          >
            {todo.text}
            <button onClick={() => handleToggleTodo(todo.id)}>
              {todo.completed ? "취소" : "완료"}
            </button>
            <button onClick={() => handleDeleteTodo(todo.id)}>삭제</button>
            {/*파라미터가 들어가면 함수를 다시 만들어야 함!!!*/}
          </li>
        ))}
      </ul>
    </div>
  );
};

export default App;