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

[Week4/기본/생각] 로그인/회원가입 #6

Open
wants to merge 10 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
1 change: 1 addition & 0 deletions week4/assign1/.env
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
VITE_APP_URL = "http://3.39.54.196"
20 changes: 20 additions & 0 deletions week4/assign1/.eslintrc.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
module.exports = {
root: true,
env: { browser: true, es2020: true },
extends: [
'eslint:recommended',
'plugin:react/recommended',
'plugin:react/jsx-runtime',
'plugin:react-hooks/recommended',
],
ignorePatterns: ['dist', '.eslintrc.cjs'],
parserOptions: { ecmaVersion: 'latest', sourceType: 'module' },
settings: { react: { version: '18.2' } },
plugins: ['react-refresh'],
rules: {
'react-refresh/only-export-components': [
'warn',
{ allowConstantExport: true },
],
},
}
26 changes: 26 additions & 0 deletions week4/assign1/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
.env

# 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?
45 changes: 45 additions & 0 deletions week4/assign1/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
- 로딩 / 에러 처리를 하는 방법에는 어떤 것들이 있을까?
>Try/Catch 블록:
코드에서 예외가 발생할 수 있는 부분을 try 블록에 넣고, 예외가 발생하면 catch 블록에서 이를 잡아내어 처리한다.

콜백 함수:
비동기 작업에서 종종 사용되며, 함수가 완료되었을 때 실행되는 콜백에 성공 또는 실패 로직을 작성한다.

프로미스(Promise):
ES6에 도입된 프로미스는 비동기 작업의 완료 또는 실패를 나타내는 객체로, .then()과 .catch() 메서드를 사용하여 결과를 처리한다.

async/await:
ES2017에서 도입된 async/await는 프로미스를 더 읽기 쉽게 만들어주며, try/catch와 함께 사용하여 에러를 처리한다.

로딩 상태 관리:
UI 상태 변수(예: isLoading, isError)를 사용하여 로딩 상태와 에러 상태를 관리하고, 이를 기반으로 사용자에게 피드백을 제공함.

이벤트 리스너/에미터:
특정 이벤트 발생 시 호출되는 리스너를 등록하여 에러를 처리함.

인터셉터(Interceptors):
많은 HTTP 클라이언트 라이브러리에서 제공하는 인터셉터를 사용하여 요청/응답을 가로채 에러 처리함.
- 패칭 라이브러리란 무엇이고 어떤 것들이 있을까?
>패칭 라이브러리는 웹 애플리케이션에서 외부 API 또는 서버로부터 데이터를 가져오기 위해 HTTP 요청을 보내는 작업을 돕는 라이브러리이다. 이러한 라이브러리는 HTTP 클라이언트의 역할을 하며, 개발자가 네트워크 요청을 쉽게 만들고 관리할 수 있도록 도와준다.

Fetch API,
Axios,
jQuery.ajax(),
Superagent

- 패칭 라이브러리를 쓰는 이유는 무엇일까?

간편성:
복잡한 네트워크 요청 로직을 추상화하여 개발자가 쉽게 HTTP 요청을 구성하고 실행할 수 있게 해줌.

기능성:
타임아웃, 쿠키, 헤더 설정 등의 고급 기능과 에러 처리를 쉽게 할 수 있는 기능을 제공.

프로미스 지원:
비동기 요청을 처리할 때 프로미스를 사용하여 코드의 가독성을 높이고, 비동기 코드의 복잡성을 관리할 수 있음.

브라우저 호환성:
다양한 브라우저에서 일관된 방식으로 HTTP 요청을 보낼 수 있도록 도와줌.

커뮤니티와 지원:
널리 사용되는 라이브러리는 커뮤니티의 지원을 받아 문제 발생 시 해결책을 찾기 쉽고, 지속적인 업데이트가 이루어집니다.
13 changes: 13 additions & 0 deletions week4/assign1/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<!doctype html>
<html lang="ko">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>로그인/회원가입</title>
</head>
<body>
<div id="root"></div>
<script type="module" src="/src/main.jsx"></script>
</body>
</html>
29 changes: 29 additions & 0 deletions week4/assign1/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
{
"name": "week4-assign1",
"private": true,
"version": "0.0.0",
"type": "module",
"scripts": {
"dev": "vite",
"build": "vite build",
"lint": "eslint . --ext js,jsx --report-unused-disable-directives --max-warnings 0",
"preview": "vite preview"
},
"dependencies": {
"axios": "^1.6.2",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-router-dom": "^6.19.0",
"styled-components": "^6.1.1"
},
"devDependencies": {
"@types/react": "^18.2.37",
"@types/react-dom": "^18.2.15",
"@vitejs/plugin-react": "^4.2.0",
"eslint": "^8.53.0",
"eslint-plugin-react": "^7.33.2",
"eslint-plugin-react-hooks": "^4.6.0",
"eslint-plugin-react-refresh": "^0.4.4",
"vite": "^5.0.0"
}
}
1 change: 1 addition & 0 deletions week4/assign1/public/vite.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
7 changes: 7 additions & 0 deletions week4/assign1/src/App.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
.App{
width: 100%;
Copy link
Member

Choose a reason for hiding this comment

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

호옥시 App을 화면 꽉차게 구현하고 싶었던거라면? vw, vh 등을 활용해도 좋을거같아용

height: 100%;
display: flex;
Copy link
Member

Choose a reason for hiding this comment

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

앗 꽉차는 용도가 아니라 모달처럼 띄우는 용도였던건가?? 머쓱 ㅎ.ㅎ

Copy link
Member Author

Choose a reason for hiding this comment

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

ㅎㅎㅎ 맞아여 헤헤

justify-content: center;
align-items: center;
}
Comment on lines +1 to +7

Choose a reason for hiding this comment

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

요거 전역에 들어갈 설정인가용 ?! 그러면 globalStyle에 추가해줘도 된답니댜!

Copy link
Member Author

Choose a reason for hiding this comment

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

App 컴포넌트 안에 있는 애들을 가운데로 오게하고 싶어서 한거예요!! 그래도 globalStyle에 해도 되나여??

24 changes: 24 additions & 0 deletions week4/assign1/src/App.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import GlobalStyle from "./styles/GlobalStyle"
import { ThemeProvider } from "styled-components";
import theme from "./styles/theme";
import './App.css';
import {BrowserRouter} from "react-router-dom";
import Router from "./components/Router";


function App() {


return (
<div className="App">
<ThemeProvider theme={theme}>
<BrowserRouter>
<GlobalStyle/>
<Router/>
</BrowserRouter>
</ThemeProvider>
</div>
)
}

export default App
1 change: 1 addition & 0 deletions week4/assign1/src/assets/react.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
29 changes: 29 additions & 0 deletions week4/assign1/src/components/Button.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import React from 'react';
import styled,{css} from "styled-components";

const Button = ({content,onClick,disabled}) => {
return (
<ButtonSt onClick={onClick} $disabled={disabled}>{content}</ButtonSt>

Choose a reason for hiding this comment

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

button에는 type 지정해두는거 잊지 말기 ~

Copy link
Member

Choose a reason for hiding this comment

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

옹 $이걸 붙인 이유는 그냥 disabled로 작성하면 비활성으로 인식해서 그런건가?? 이런 방법이 있었다니 ,,

Copy link
Member Author

Choose a reason for hiding this comment

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

syled-component에 보낼 때 $를 붙여서 보내면 dom에는 영향을 미치지 않고 계산하는데에만 쓰인다고 하더라구!!

)
}

const ButtonSt=styled.button`
Copy link
Member

Choose a reason for hiding this comment

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

호옥시 Button뒤에 St는 스타일 컴포넌트임을 알기 쉽게 하기 위해선가용?

Copy link
Member

Choose a reason for hiding this comment

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

객체로 styledcomponent 묶는거 해보면 도움될거같앙!!

Copy link
Member Author

Choose a reason for hiding this comment

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

맞아요!! 버튼 스타일... 객체로 묶어보겠슴당 ㅎㅎ

width: 100%;
height: 40px;
border-radius: 10px;
border: none;
font-size:18px;
Comment on lines +11 to +15

Choose a reason for hiding this comment

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

px 단위를 쓰는 이유가 있을까요?! width/height, font-size와 같은 반응형 구현이 필요한 부분은 rem을 쓰는걸 추천합니당!!

Copy link
Member Author

Choose a reason for hiding this comment

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

아 맞다!! 저번에도 한번 추천받아서 생각해두고 있었는데 미처 신경을 못썼댜,,,🥲

font-weight: 800;
background-color: ${({ $disabled,theme }) => ($disabled ? theme.colors.mainColor : '#ccc')};
color: ${({theme})=>theme.colors.white};
Comment on lines +17 to +18

Choose a reason for hiding this comment

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

theme 사용부터 props로 동적 스타일링까지!! 넘넘 완벽합니당🔥





&:hover{
/* background-color: #f5d6d2; */
cursor: pointer;
Copy link
Member

Choose a reason for hiding this comment

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

섬세해요 ,,

}
`

export default Button
21 changes: 21 additions & 0 deletions week4/assign1/src/components/InputBox.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import React from 'react'
import {Input,Label} from "../styles/common/CommonStyle"
import { styled } from 'styled-components'

const InputBox = ({name,label,placeholder,value,onChange}) => {
return (
<InputContaier>
<Label htmlFor={name}>{label}</Label>
<Input type='text' name={name} placeholder={placeholder} value={value} onChange={(e)=>onChange(e.target.value)}></Input>
</InputContaier>
)
}

const InputContaier=styled.div`
width: 100%;
display: flex;
justify-content: space-between;
align-items: center;
`

export default InputBox
17 changes: 17 additions & 0 deletions week4/assign1/src/components/Router.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import React from 'react'
import {Routes,Route} from "react-router-dom";
import {Login,Mypage,Signup} from "../pages/index";

const Router = () => {
return (
<>
<Routes>
<Route path="/" element={<Login/>}/>
<Route path="/signup" element={<Signup/>}/>
<Route path="/mypage/:userId" element={<Mypage/>}/>
</Routes>
</>
)
}

export default Router
9 changes: 9 additions & 0 deletions week4/assign1/src/main.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import React from 'react'
import ReactDOM from 'react-dom/client'
import App from './App.jsx'

ReactDOM.createRoot(document.getElementById('root')).render(
<React.StrictMode>
<App />
</React.StrictMode>,
)
94 changes: 94 additions & 0 deletions week4/assign1/src/pages/Login.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
import React, { useState,useEffect } from 'react'
import styled from "styled-components";
import { Wrapper} from '../styles/common/CommonStyle';
import Button from '../components/Button';
import {useNavigate} from "react-router-dom";
import axios from "axios";
import InputBox from '../components/InputBox';

/**로그인 페이지 */
const Login = () => {
const API_URL = import.meta.env.VITE_APP_URL;

Choose a reason for hiding this comment

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

env에 URL 저장해놓고 불러온거 아쥬아주 좋습니다!
참고로 axios를 인스턴스화 해서 정의 해놓고 사용하는 방법도 있습니다!
이 자료를 참고해보세용 ~

Copy link
Member Author

Choose a reason for hiding this comment

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

옹 나중에 참고해야겠어요,,✨

const nav = useNavigate();

//넘길 정보들
const [username,setUsername]=useState("");
const [password,setPassword]=useState("");

//그ㅡ 외
const [canlogin,setCanLogin]=useState(false);

//로그인 버튼 활성화
useEffect(()=>{
username&&password ? setCanLogin(true): setCanLogin(false);
},[username,password]);
Comment on lines +22 to +24

Choose a reason for hiding this comment

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

활성화 처리 귯 !!


const submitLogin=()=>{
axios.post(`${API_URL}/api/v1/members/sign-in`,{
"username":username,
"password":password
}).then(res=>{
nav(`/mypage/${res.data.id}`);
}).catch(err=>{

})
}

return (
<Wrapper>
<Container>
<h1>Login</h1>
<div className='inputsContainer'>
<InputBox name="id" label="ID" placeholder="아이디를 입력해주세요" value={username} onChange={setUsername}/>
Copy link
Member

Choose a reason for hiding this comment

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

옹 InputBox라는 컴포넌트를 만들고 걔에 onchange 이벤트 처리함수만 다르게 넘겨주면서 처리했구나!! 이런 방법도 있었군..!!

<InputBox name="pw" label="PASSWORD" placeholder="비밀번호를 입력해주세요" value={password} onChange={setPassword}/>
</div>
<Button disabled={canlogin} content="로그인" onClick={submitLogin}/>
<button id='move-pw' onClick={()=>{nav('/signup')}}>회원가입 하러가기</button>
</Container>
</Wrapper>
)
};

const Container=styled.div`
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
gap: 10px;

.inputsContainer{
Copy link
Member

Choose a reason for hiding this comment

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

난 개인적으로는 styledcomponent로 한번 감싼상황이라면, 그 안에 css 지정이 필요한경우 추가로 styledcomponent를 만들어서 걔로 css를 지정하는편이얌! 움 통일성?을 주는게 개인적으론 이해가 편해서 그랬던건데 혹시 수연이는 분리 안한 이유가 따로 있는지 궁금해!

Copy link
Member Author

Choose a reason for hiding this comment

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

따로 이유는 없구.. 간단한 내용이면 따로 안만들고 하는 편인거 같오!! 가독성 편에선 따로 만드는게 더 좋을듯!!!

width: 100%;
display: flex;
flex-direction: column;
gap:10px;
margin: 30px 0;
}

.input{
Copy link
Member

Choose a reason for hiding this comment

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

난 금붕어라 이렇게 여러 선택자있을때 헤헤 이해속도가 느려서 헤헹

Copy link
Member Author

Choose a reason for hiding this comment

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

ㅋㅋㅋㅋㅋㅋㅋ 근데 나중에 보면 어떤건지 찾기 좀 힘들긴 하겠다!! 따로 만들어주는 습관 가져야게써

width: 100%;
display: flex;
justify-content: space-between;
align-items: center;

}

#move-pw{
width: 100%;
height: 40px;
font-size: 18px;
font-weight: 800;
background-color: transparent;
border: none;
color: ${({theme})=>theme.colors.grayColor};

&:hover{
color: ${({theme})=>theme.colors.pointColor};
}
}

`


export default Login
Loading