Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[3주차-ts] 이상형 with TS #6

Open
wants to merge 17 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions node_modules/.yarn-integrity

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"dependencies": {}
}
220 changes: 108 additions & 112 deletions week3/src/App.jsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { useState, useRef, useEffect } from "react";
import {
StyledRoot,
GameTitle,
GameRound,
GameSection,
GameResetButton,
WinnerSection,
StyledRoot,
GameTitle,
GameRound,
GameSection,
GameResetButton,
WinnerSection,
} from "./style";
import jongIn from "@/assets/image/김종인.jpg";
import seHun from "@/assets/image/오세훈.jpg";
Expand All @@ -25,115 +25,111 @@ import kyoungSoo from "@/assets/image/도경수.jpg";
import minHyung from "@/assets/image/이민형.jpg";

function App() {
// 월드컵 참여자들 배열
const gameInfo = [
{ img: jongIn, name: "김종인" },
{ img: seHun, name: "오세훈" },
{ img: baekHyun, name: "변백현" },
{ img: junMyeon, name: "김준면" },
{ img: jaeHyun, name: "정재현" },
{ img: doYoung, name: "김도영" },
{ img: jungWoo, name: "김정우" },
{ img: dongHyuk, name: "이동혁" },
{ img: jiYong, name: "권지용" },
{ img: jaeMin, name: "나재민" },
{ img: jeNo, name: "이제노" },
{ img: eunWoo, name: "차은우" },
{ img: jungHan, name: "윤정한" },
{ img: hoShi, name: "권호시" },
{ img: kyoungSoo, name: "도경수" },
{ img: minHyung, name: "이민형" },
];
// 배열 랜덤으로 재정렬
const randomGameInfo = gameInfo.sort(() => Math.random() - 0.5);
// 월드컵 참여자들 배열
const gameInfo = [
{ img: jongIn, name: "김종인" },
{ img: seHun, name: "오세훈" },
{ img: baekHyun, name: "변백현" },
{ img: junMyeon, name: "김준면" },
{ img: jaeHyun, name: "정재현" },
{ img: doYoung, name: "김도영" },
{ img: jungWoo, name: "김정우" },
{ img: dongHyuk, name: "이동혁" },
{ img: jiYong, name: "권지용" },
{ img: jaeMin, name: "나재민" },
{ img: jeNo, name: "이제노" },
{ img: eunWoo, name: "차은우" },
{ img: jungHan, name: "윤정한" },
{ img: hoShi, name: "권호시" },
{ img: kyoungSoo, name: "도경수" },
{ img: minHyung, name: "이민형" },
];
// 배열 랜덤으로 재정렬
const randomGameInfo = gameInfo.sort(() => Math.random() - 0.5);

const [round, setRound] = useState("16강");
const matchWinners = useRef([]);
const [fighterList, setFighterList] = useState(randomGameInfo);
const [gameEnd, setGameEnd] = useState(false);
const [round, setRound] = useState("16강");
const matchWinners = useRef([]);
const [fighterList, setFighterList] = useState(randomGameInfo);
const [gameEnd, setGameEnd] = useState(false);
Comment on lines +50 to +53
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
const [round, setRound] = useState("16강");
const matchWinners = useRef([]);
const [fighterList, setFighterList] = useState(randomGameInfo);
const [gameEnd, setGameEnd] = useState(false);
const [round, setRound] = useState<string>("16강");
const matchWinners = useRef<array>([]);
const [fighterList, setFighterList] = useState<여기도 타입 지정>(randomGameInfo);
const [gameEnd, setGameEnd] = useState<boolean>(false);

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

state, ref에도 타입지정 필요합니다!!
react-hook : 서히 벨로그

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Happhee 초기값 설정하면 자동으로 타입추론이 되긴 해요 !!~@

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@joohaem 그건 아는데 !! 그래도 명시 해주는게 맞는방법아니야?!! 추론하게 하는게 타입스크립트를 쓰는 이유가 맞는걸까? 라는 의문이 들었오!

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

넵넵 빨간줄 안떠서 그냥 그대로 한 거 같아유 수정해놓을게요!


// 현재 몇 라운드인지
const countRoundNum = () => {
return matchWinners.current.length + 1;
};
// 이번 강에는 총 몇 번의 라운드가 있는지
const totalRoundNum = () => {
return Math.ceil(
(fighterList.length + matchWinners.current.length * 2) / 2
);
};
// 승자를 골랐을 때
const getSelectWinner = (pos) => {
matchWinners.current.push(fighterList[pos]);
setFighterList(fighterList.slice(2));
};
// 다시 게임을 시작하는 함수
const playAgain = () => {
setGameEnd(false);
matchWinners.current = [];
setFighterList(randomGameInfo);
setRound("16강");
};
// 화면이 리렌더링 될 때 마다 참가자들 배열과 승리자들 배열 확인
useEffect(() => {
if (fighterList.length === 0 && matchWinners.current.length >= 8) {
setFighterList(matchWinners.current);
setRound("8강");
matchWinners.current = [];
} else if (fighterList.length === 0 && matchWinners.current.length >= 4) {
setFighterList(matchWinners.current);
setRound("4강");
matchWinners.current = [];
} else if (fighterList.length === 0 && matchWinners.current.length >= 2) {
setFighterList(matchWinners.current);
setRound("결승");
matchWinners.current = [];
} else if (fighterList.length === 0 && matchWinners.current.length === 1) {
setGameEnd(true);
}
});
// 현재 몇 라운드인지
const countRoundNum = () => {
return matchWinners.current.length + 1;
};
// 이번 강에는 총 몇 번의 라운드가 있는지
const totalRoundNum = () => {
return Math.ceil((fighterList.length + matchWinners.current.length * 2) / 2);
};
// 승자를 골랐을 때
const getSelectWinner = (pos) => {
matchWinners.current.push(fighterList[pos]);
setFighterList(fighterList.slice(2));
};
Comment on lines +64 to +67
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

요기도 매개변수 타입 지정!!!!!!!!🚨🚨🚨🚨🚨🚨

타입스크립트에서 변수에는 타입 무조건 갈기자🚨🚨🚨

// 다시 게임을 시작하는 함수
const playAgain = () => {
setGameEnd(false);
matchWinners.current = [];
setFighterList(randomGameInfo);
setRound("16강");
};
// 화면이 리렌더링 될 때 마다 참가자들 배열과 승리자들 배열 확인
useEffect(() => {
if (fighterList.length === 0 && matchWinners.current.length >= 8) {
setFighterList(matchWinners.current);
setRound("8강");
matchWinners.current = [];
} else if (fighterList.length === 0 && matchWinners.current.length >= 4) {
setFighterList(matchWinners.current);
setRound("4강");
matchWinners.current = [];
} else if (fighterList.length === 0 && matchWinners.current.length >= 2) {
setFighterList(matchWinners.current);
setRound("결승");
matchWinners.current = [];
} else if (fighterList.length === 0 && matchWinners.current.length === 1) {
setGameEnd(true);
}
});

if (!gameEnd) {
// 게임이 끝나지 않았다면
return (
<StyledRoot>
<GameTitle>내가 사랑하는 남성 월드컵 {round}</GameTitle>
<GameRound>
{countRoundNum()}/{totalRoundNum()}
</GameRound>
<GameSection>
{fighterList.map((fighter, index) => {
if (index < 2) {
return (
<article onClick={() => getSelectWinner(index)}>
<img src={fighter.img} />
<div>{fighter.name}</div>
</article>
);
}
})}
<p>VS</p>
</GameSection>
</StyledRoot>
);
} else {
// 게임이 끝났다면
return (
<StyledRoot>
<GameTitle>
내가 가장 사랑하는 남성은 {matchWinners.current[0].name}
</GameTitle>
<WinnerSection>
<p>👑</p>
<article>
<img src={matchWinners.current[0].img} />
<div>{matchWinners.current[0].name}</div>
</article>
</WinnerSection>
<GameResetButton onClick={playAgain}>다시하기</GameResetButton>
</StyledRoot>
);
}
if (!gameEnd) {
// 게임이 끝나지 않았다면
return (
<StyledRoot>
<GameTitle>내가 사랑하는 남성 월드컵 {round}</GameTitle>
<GameRound>
{countRoundNum()}/{totalRoundNum()}
</GameRound>
<GameSection>
{fighterList.map((fighter, index) => {
if (index < 2) {
return (
<article onClick={() => getSelectWinner(index)}>
<img src={fighter.img} />
<div>{fighter.name}</div>
</article>
);
}
})}
<p>VS</p>
</GameSection>
</StyledRoot>
);
} else {
// 게임이 끝났다면
return (
<StyledRoot>
<GameTitle>내가 가장 사랑하는 남성은 {matchWinners.current[0].name}</GameTitle>
<WinnerSection>
<p>👑</p>
<article>
<img src={matchWinners.current[0].img} />
<div>{matchWinners.current[0].name}</div>
</article>
</WinnerSection>
<GameResetButton onClick={playAgain}>다시하기</GameResetButton>
</StyledRoot>
);
}
}

export default App;
Empty file removed week3/src/index.css
Empty file.
24 changes: 24 additions & 0 deletions week3_ts/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*

node_modules
dist
dist-ssr
*.local

# Editor directories and files
.vscode/*
!.vscode/extensions.json
.idea
.DS_Store
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?
17 changes: 17 additions & 0 deletions week3_ts/globalStyle.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
@font-face {
font-family: "HaenamFont";
src: url("https://cdn.jsdelivr.net/gh/projectnoonnu/[email protected]/HaenamFont.woff")
format("woff");
font-weight: normal;
font-style: normal;
}

body {
font-family: "HaenamFont";
height: 100vh;
}

/*px to rem*/
html {
font-size: 62.5%;
}
14 changes: 14 additions & 0 deletions week3_ts/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Vite App</title>
<link rel="stylesheet" href="./globalStyle.css" />
<link rel="stylesheet" href="./reset.css" />
</head>
<body>
<div id="root" style="height: 100%"></div>
<script type="module" src="/src/index.tsx"></script>
</body>
</html>
27 changes: 27 additions & 0 deletions week3_ts/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
{
"name": "week3_ts",
"private": true,
"version": "0.0.0",
"scripts": {
"dev": "vite",
"build": "tsc && vite build",
"preview": "vite preview"
},
"dependencies": {
"@types/node": "^17.0.43",
"@types/react-router-dom": "^5.3.3",
"@types/styled-components": "^5.1.25",
"path": "^0.12.7",
"react": "^18.2.0",
"react-dom": "^18.0.0",
"styled-components": "^5.3.5"
},
"devDependencies": {
"@types/react": "^18.0.14",
"@types/react-dom": "^18.0.0",
"@vitejs/plugin-react": "^1.3.0",
"react-router-dom": "^6.3.0",
"typescript": "^4.6.3",
"vite": "^2.9.9"
}
}
Loading