ㅇㅇㅈ Blog

프론트엔드 수행중

0%

login form

로그인 폼 만들기

2주차 실습과제

  • Form handling width state
  • State Handling with useEffect
  • State handling with Redux
  • component Handling with state

간단하게 매니저님이 서버를 만들어 주시고 id와 pw를 맞게 입력하면 로그인, 틀릴경우에 에러코드에 맞게 메세지를 출력하는 실습

로그인 컴포넌트

input으로 id와 password를 받아 각각 setId와 setPassword로 저장

저장된 id와 password를 body에 넣어주고,

axios post요청 할 때 url 주소와 body를 같이 넘겨 주면 된다.

그리고 loading의 boolean 값으로 로그인버튼의 disable을 조절 해 줄 예정 이므로

로그인 버튼이 눌리면 setLoading으로 값을 true로 변경 시켜 준다

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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
import React, { useState, useEffect, useRef } from 'react';
import { useDispatch } from 'react-redux';
import { loginUser } from '../reducer/userSlice.js';
import axios from 'axios';

function LoginComponent() {
const dispatch = useDispatch();
const [id, setId] = useState('');
const [password, setPassword] = useState('');
const [loading, setLoading] = useState(false);
const [msg, setMsg] = useState('');
const idInput = useRef(null);
const pwInput = useRef(null);

const body = {
id,
password,
};

useEffect(() => {
const timeout = setTimeout(() => {
setMsg('');
}, 1500);
return () => {
clearTimeout(timeout);
};
}, [msg]);

// 로그인 요청
const getUsers = async () => {

};
// 로그인
const LoginFunc = (e) => {
e.preventDefault();
setLoading(true)
getUsers();
};
// 에러 핸들
const handleError = (response) => {

};

// input handle
const handleChangeID = (e) => {
setId(e.target.value);
};
const handleChangePW = (e) => {
setPassword(e.target.value);
};

return (
<>
<h1>LoginComponent</h1>
<form onSubmit={LoginFunc}>
<label htmlFor='id'>ID : </label>
<input
type='text'
ref={idInput}
value={id}
id='id'
onChange={handleChangeID}
/>

<br />
<label htmlFor='password'>Password : </label>
<input
type='password'
id='password'
ref={pwInput}
value={password}
onChange={handleChangePW}
/>
<br />
<br />
<button disabled={loading} type='submit'>
로그인
</button>
<br />
</form>

<br />
{msg}
<br />
</>
);
}

export default LoginComponent;

axios 요청

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
//  로그인 요청
const getUsers = async () => {
try {
const response = await axios
.post('https://st-fe34.herokuapp.com/api/login', body)
.then((res) => res.data)
.catch((error) => {
setMsg(error.message);
});
handleError(response);
setLoading(false);
} catch (err) {
console.log(err);
} finally {
setLoading(false);
}
};

post 요청시에는 body에 정보를 담아서 보내고
get 요청시에는 ?id= 같은 주소에 파라미터에 포함시켜 보낸다
둘의 차이점에 대해서 좀 더 자세히 공부 해볼것..

어쨋든 요청을 보내고 나면
body 값에 따라 다른 코드를 받게된다

받은 code에 따라 메세지를 출력 해주는 메소드를 작성 한다

조건이 몇개 되지 않아 else if 로 작성 해도 되지만 switch로 작성 해보았다.

그리고 마지막에 정상코드일시 dispatch를 통해 userInfo를 담아 store의 loginUser action을 호출 한다

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
const handleError = (response) => {
switch (response.code) {
case 400:
setMsg('ID와 PW를 입력해주세요');
break;
case 401:
setMsg('존재하지 않는 ID 입니다');
idInput.current.focus();
break;
case 402:
setMsg('비밀번호가 틀렸습니다');
pwInput.current.focus();
break;
default:
dispatch(loginUser(response.userInfo));
}
};

store의 userSlice

컴포넌트에서 dispatch로 loginUser액션을 호출하면서 넘긴 값은 payload에 담겨서 온다

받아온 값을

store의 state값으로 저장 해주면 된다

그리고 로그아웃 버튼을 누르면 clearUser 액션을 호출하게 되고

clearUser액션을 통해 스토어의 값들을 비워 주면 된다.

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
import { createSlice } from '@reduxjs/toolkit';

export const userSlice = createSlice({
name: 'user',
initialState: {
name: '',
id: '',
isLoading: false, // optional
isLogin: null,
check: false,
},
reducers: {
loginUser: (state, { payload }) => {
state.name = payload.name;
state.id = payload.id;
state.isLoading = true;
state.isLogin = true;
},
clearUser: (state) => {
state.name = '';
state.id = '';
state.isLoading = false;
state.isLogin = false;
},
},
});

export const { loginUser, clearUser } = userSlice.actions;
export default userSlice.reducer;

mypage component

store에 있는 state를 불러올때는 useSelector 훅을 사용해야 한다

로그인했을때 store에 저장해둔 user의 name을 출력해준다

로그아웃 버튼을 눌렀을때는 clearUser 액션을 호출해준다

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import React from 'react';
import { useSelector, useDispatch } from 'react-redux';
import { clearUser } from '../reducer/userSlice.js';

function MyPage() {
const user = useSelector((state) => state.user);
const dispatch = useDispatch();

const LogoutFunc = () => {
dispatch(clearUser());
};

return (
<>
<h1>MyPage</h1>
<p>{user.name}님, 안녕하세요!</p>
<button onClick={LogoutFunc}>로그아웃</button>
</>
);
}

export default MyPage;


App.jsx

1
2
3
4
5
6
7
8
9
10
11
12
13
import React from 'react';
import { useSelector } from 'react-redux';

import InputComponent from './component/InputComponent';
import MyPage from './component/MyPage';

function App() {
const user = useSelector((state) => state.user);

return <div>{user.isLogin ? <MyPage /> : <LoginComponent />}</div>;
}

export default App;

store에 있는 isLogin 값에 따라 로그인창이 보일건지 로그아웃창이 보일건지 설정