React를 사용하지 않고 단순한 HTML이나 ejs, pug 등을 사용했을 때 form을 작성하는 방식은 대체적으로 form의 속성으로 action, method를 주는 것이었다.
그러나 React는 그런 방식으로 (물론 만들면 할 수는 있지만) 백엔드와 소통하지 않는다.
다음과 같은 express 백엔드가 있다고 해보자.
결국 req.body에서 정보를 빼와서 활용하는 방식이다. 그렇다면 문제는 react에서 어떤 방식으로 form을 작성해서 백 쪽으로 정보를 전달해줄 것인가가 문제다.
// POST 로그인
app.post("/api/users/login", (req, res) => {
// 해당 email이 있는지 확인
User.findOne({ email: req.body.email }, (error, user) => {
// 에러는 500
if (error) {
return res.status(500).json({ error: "오류" });
}
// 찾는 유저가 없다?
if (!user) {
return res.status(403).json({
loginSuccess: false,
message: "해당되는 이메일이 없습니다.",
});
}
// email이 맞으니 pw가 일치하는지 검증합니다.
if (user) {
const checkPW = () => {
bcrypt.compare(req.body.password, user.password, (error, isMatch) => {
if (error) {
return res.status(500).json({ error: "something wrong" });
}
if (isMatch) {
// 비밀번호가 맞으면 token을 생성해야 합니다.
// secret 토큰 값은 특정 유저를 감별하는데 사용합니다.
// 토큰 생성
const token = jwt.sign({ random: user._id }, SECRET_TOKEN);
// 해당 유저에게 token값 할당 후 저장
user.token = token;
user.save((error, user) => {
if (error) {
return res.status(400).json({ error: "something wrong" });
}
// DB에 token 저장한 후에는 cookie에 토큰을 저장하여 이용자를 식별합니다.
return res
.cookie("x_auth", user.token)
.status(200)
.json({ loginSuccess: true, userId: user._id });
});
} else {
return res.status(403).json({
loginSuccess: false,
message: "비밀번호가 틀렸습니다.",
});
}
});
};
checkPW();
}
});
});
input에 name을 열심히 적어서 전달한 것과 달리 React에서는 state를 사용하기로 했다. input에 뭔가를 적으면 state 값으로 저장되고 그 값을 body로 모아서 post를 날리는 것이다. input에 name을 신경쓰지 않아도 되고 label에 for을 안 적어도 된다는 장점이 있다. 수고를 던 셈이다!
* req.body에서 뽑아 쓴 변수명은 전달하는 body의 값과 동일해야 합니다. 위에서 req.body.email을 뽑아 썼는데 프론트 단에서 body를 Email로 보내면 변수명이 일치 하지 않으므로 에러를 띄웁니다. 이 문제 때문에 왜 안되는지 30분이나 헤맸습니다...
post 결과는 axios가 반환하는 res 값에 존재한다. 달콤하게 맛보자.
import React, { useState } from "react";
import axios from "axios";
export default () => {
const [Email, SetEmail] = useState("");
const [Password, SetPassword] = useState("");
const emailHandler = (e) => {
e.preventDefault();
SetEmail(e.target.value);
};
const passwordHandler = (e) => {
e.preventDefault();
SetPassword(e.target.value);
};
const submitHandler = (e) => {
e.preventDefault();
// state에 저장한 값을 가져옵니다.
console.log(Email);
console.log(Password);
let body = {
email: Email,
password: Password,
};
axios
.post("http://localhost:5000/api/users/login", body)
.then((res) => console.log(res));
};
return (
<>
<div
style={{
display: "flex",
justifyContent: "center",
alignItems: "center",
width: "100%",
height: "100vh",
}}
>
<form
onSubmit={submitHandler}
style={{ display: "flex", flexDirection: "Column" }}
>
<label>Email</label>
<input type="email" value={Email} onChange={emailHandler}></input>
<label>Password</label>
<input
type="password"
value={Password}
onChange={passwordHandler}
></input>
<button type="submit">Login</button>
</form>
</div>
</>
);
};
'React, Next, Redux > ⚛ React.JS' 카테고리의 다른 글
React에서 radio button 사용법 (0) | 2020.06.05 |
---|---|
HOC을 통한 인증 미들웨어 (0) | 2020.05.30 |
react-slick을 이용한 캐러셀 슬라이더 (0) | 2020.04.18 |
Nested Routing (0) | 2020.04.14 |
SPA에서 뒤로가기, 새로고침 시 404 Not Found 오류 해결 (0) | 2020.04.10 |