8/8 과제 제출 - AI 서비스 완성! AI 웹개발 취업캠프 [NIPA/정보통신산업진흥원]

Alicia·2023년 8월 8일
0

AI_Web_nipa

목록 보기
13/31

과제 : App06.js 실습하며 정리
jsx와 useState 익숙해지기
lotto.html (js) -> react 애플리케이션으로 변경하기 (스타일 커스터마이징)

index.js

리액트애플리케이션이 실행될때 가장먼저실행되는 진입점(entrypoint) 역할 을수
행한다.

import React from "react";
import ReactDOM from "react-dom/client";
import "./index.css";
import App from "../src/App06";
import reportWebVitals from "./reportWebVitals";

const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>
);

// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
reportWebVitals();

여기에서 보여줄 최초 컴포넌트를 import하고

javascript(node)로 작성한 소스코드를 react.js 로 변환하기

addUrl.js
정적 파일인 HTML, CSS 및 JavaScript 파일을 서비스하는 간단한 웹 서버

const http = require("http");
const fs = require("fs");
const url = require("url");
var morgan = require("morgan");

var logger = morgan("tiny");
const hostname = "127.0.0.1"; // localhost
const port = 3000;

const server = http.createServer(function (req, res) {
  //서버 앱 내에서 접근할 경로를 해석한다
  const pageURL = req.url;
  const pathname = url.parse(pageURL, true).pathname;

  logger(req, res, function (err) {
    if (err) return console.log(err);

    if (pathname === "/") {
      fs.readFile("./public/lotto.html", function (err, data) {
        res.statusCode = 200;
        res.writeHead(200, { "Content-Type": "text/html" });
        res.end(data);
      });
    } else if (pathname === "/style.css") {
      fs.readFile("./public/style.css", "utf8", function (err, data) {
        res.writeHead(200);
        res.write(data);
        res.end();
      });
    } else if (pathname === "/script.js") {
      fs.readFile("./public/script.js", "utf8", function (err, data) {
        res.writeHead(200);
        res.write(data);
        res.end();
      });
    }
  });
});

server.listen(port, hostname, () => {
  console.log(`Server running at http://${hostname}:${port}/`);
});

//lotto.html -->로또번호 6자리 랜덤추첨기능

<!DOCTYPE html>
<html lang="ko">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>로또 추첨 게임</title>
  <link href="style.css" rel="stylesheet">
</head>
<body>
  <div class="container">
    <div class="lotto">
      <h3><span id="today"></span>로또 번호 추첨</h3>
      <div class="numbers"></div>
      <button id="draw">추첨</button><button id="reset">다시</button>
    </div>
  </div>
  <script src="script.js"></script>

</html>

App06.js

import { useState } from "react";
import "./App06.css";

function App() {

//useState 를 사용하여 상태 관리
// lottoNumbers: 로또 번호를 저장하는 배열
  //setLottoNumbers: lottoNumbers 배열의 값을 업데이트하는 함수
  const [lottoNumbers, setLottoNumbers] = useState([]);


// 현재날짜 가져오기
  const today = new Date();
  const year = today.getFullYear();
  const month = today.getMonth() + 1;
  const date = today.getDate();
  const now = `${year}년 ${month}월 ${date}일 `;

  return (
    <div className="container">
      <div className="lotto">
        <img src="/lottery.png" alt="money"></img>
        <h3>
          <span>{now}</span>
        </h3>
        <div className="title">로또 번호 추첨</div>
        <div className="numbers">
          {lottoNumbers.map((num, idx) => {
            return (
              <div className="eachnum" key={idx}>
                {num}
              </div>
            );
          })}
        </div>
        
        //"추첨" 버튼 클릭 시 로또 번호 추첨: lottoNumbers 배열을 빈 배열로 초기화한다. 
        <button
          onClick={() => {
          //여기서 왜 또 지역변수로 배열을 선언해야 하는지 의문이 있었는데 
          setLottoNumbers 함수는 이전 lottoNumbers 배열의 상태를 변경하는 것이 아니라 
          새로운 배열을 할당해야 한다. 그렇지 않으면 React는 상태가 변경되지 않았다고 
          감지하여 화면을 업데이트하지 않을 수 있다.

		따라서 setLottoNumbers 함수를 호출할 때 
        새로운 배열을 생성하여 상태를 업데이트해야 합다고 알게되었다. 
           
           const lottoNumbers = [];
            
            while (lottoNumbers.length < 6) {
              let ran = Math.floor(Math.random() * 45) + 1;
              if (lottoNumbers.indexOf(ran) === -1) {
                lottoNumbers.push(ran);
              }
            }
            setLottoNumbers(lottoNumbers);
          }}>
          추첨
        </button>
        <button
          onClick={() => {
            setLottoNumbers([]);
          }}>
          다시
        </button>
      </div>
    </div>
  );
}

export default App;

스타일은 같은 경로에 App06.css파일을 만들어 링크

@charset "utf-8";

@font-face {
  font-family: 'CookieRun-Regular';
  src: url('https://cdn.jsdelivr.net/gh/projectnoonnu/noonfonts_2001@1.1/CookieRun-Regular.woff') format('woff');
  font-weight: normal;
  font-style: normal;
}

*{ 
  font-family: 'CookieRun-Regular';
  box-sizing: border-box;
  color: #ffffff
}

html{
  font-size: 32px;
}

body{
  margin: 0;
}

.container{
  width: 500px;
  height: 100vh;
  margin: 0 auto;
  display: flex;
  justify-content: center;
  align-items: center;
  background: #1B1926;
}

img {
    margin-top: 30px;
}

.lotto{
  width: 420px;
  height: 800px;
  text-align: center;
  //배경색 그래디언트
  background: linear-gradient(to bottom right, #3747A6, #BF2011); 
  border-radius: 50px;
}

h3 {
    margin: 20px 0;
}


.numbers{
  width: 420px;
  padding: 1rem 1.2rem;
  display: flex;
  flex-wrap : wrap;
  justify-content: space-around;
  align-items: center;
}

.eachnum{
  font-size: 0.75em;
  width: 40px;
  height: 40px;
  border: 1px solid white;
  border-radius: 25px;
  padding: 1.1rem;
  margin: 10px;
  margin-bottom: 20px;
  color: white;
  /* background-color: red; */
  display: flex;
  justify-content: center;
  align-items: center;
  //그림자 효과
  box-shadow: 0 0 10px 0px rgba(255, 255, 255, 0.9),
  0 0 1px 5px rgba(255, 255, 255, 0.1),
  0 0 5px 10px rgba(255, 255, 255, 0.2),
  0 0 30px 15px rgba(255, 255, 255, 0.0),
  0 10px 30px 20px rgba(255, 255, 255, 0.1);
}

button{
  font-size: 0.9em;
  width: 40%;
  height: 1.8rem;
  border: none;
  border-radius: 16px;
  color: #1B1926;
  background-color: #F2BC57;
  cursor: pointer;
  margin-right: 10px;
  text-align: center;
}

button:active{
  font-size: 0.6em;
  width: 105px;
  height: 42px;
}

완성 결과

npm start

0개의 댓글