본문으로 바로가기

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>
    </>
  );
};

 

 

 


darren, dev blog
블로그 이미지 DarrenKwonDev 님의 블로그
VISITOR 오늘 / 전체