스프링 부트 - Backend
리액트 - Frontend
로그인 기능을 위해 form에 작성한 유저 정보를 스프링 서버로 전송하는 작업을 하고 있다.
form의 정보를 작성하는 내용에 따라 변경시키는 건 useState를 사용하고 있다.
스프링도 리액트도 완전 처음 쓰는 프레임워크라서 영...모르겠다 싶었는데 여러 블로그를 보다보니 감이 잡힌다.
useState 선언
const [userid, setId] = useState('');
const [password, setPW] = useState('');
앞은 사용할 변수명, 뒤는 변수값 변경에 사용할 함수명이다. useState()안에 작성하는 매개변수는 초기화하는 값.
정확하지는 않은데, 변수 정의와 사용할 함수가 같은 scope 안에 있어야 작동한다. 변수를 다른 함수에서도 사용해야 해서 변수만 가장 밖 전역변수로 정의했는데 사용이 불가능했다.
또, 같은 기능이라고 해서 같은 이름의 함수를 사용하면 안 된다...이건 좀 별로였음. 하나를 재사용하고 싶었는데 안 돼서 당황했었다.
form은 html형식으로 작성했다. onSubmit에 전송에 사용할 함수를 넣어주면 된다. 버튼이 submit 형식이기 때문에 버튼을 누르면 onSubmit에서 정한 함수가 실행된다. 굿~
<form id={"loginform"} onSubmit={sendForm}>
<p><input type={"text"} name={"ID"} placeholder={"ID"} value={userid} onChange={handleChangeId}/></p>
<p><input type={"text"} name={"Password"} placeholder={"Password"} value={password} onChange={handleChangePW}/></p>
<button type={"submit"}>login</button>
</form>
Submit
const sendForm = async (e) => {
e.preventDefault();
await axios.post("/login/welcome", {
'userId':userid,
'userPW':password
}, {"Content-Type": 'application/json'})
.then(function (res) {
console.log(res);
});
}
기존 event가 하는 일을 무시하도록 해주고,
axios의 post 형식에 맞춰 url, data, config를 작성해준다.
세 매개변수를 각 변수로 만들수도 있다. 지금은 내용이 많지 않아서 그냥 작성했다.
login.js 전문 ↓
Bulma로 css 적용을 했기 때문에 코드가 조금 달라졌지만, class가 추가된 것뿐이니 당황하지 마시길
function Login() {
const [userid, setId] = useState('');
const [password, setPW] = useState('');
const navigate = useNavigate();
const handleChangeId = (event) => {
setId(event.target.value);
}
const handleChangePW = (event) => {
setPW(event.target.value);
}
const sendForm = async (e) => {
e.preventDefault();
await axios.post("/login/welcome", {
'userId':userid,
'userPW':password
}, {"Content-Type": 'application/json'})
.then(function (res) {
console.log(res);
});
}
return (
<form id={"loginform"} onSubmit={sendForm}>
<div class={"control"}>
<p><input class="input login is-info" type={"text"} placeholder={"ID"} value={userid}
onChange={handleChangeId}/></p>
<p><input class="input login is-info" type={"text"} placeholder={"Password"} value={password}
onChange={handleChangePW}/></p>
</div>
<button class="button is-info is-rounded" type={"submit"}>login</button>
</form>
);
};
스프링에서 json 받기
굉장히 신기했던 점
전송했던 json 객체를 스프링에서 작성한 class로 받아올 수 있다.
@PostMapping(value = "/login/welcome")
public String login(@RequestBody Login user) {
log.info("user", user);
return "101";
}
이 때 class를 특정하게 만들어야 한다.
처음에는 Getter, Setter 없이 내가 함수를 만들어서 구현했는데 동작이 안 되어서 검색을 해봤다.
@Getter
@ToString
@NoArgsConstructor(access = AccessLevel.PROTECTED)
//@Setter
class Login {
private String userId;
private String userPW;
@Builder
private Login(String id, String pw){
this.userId = id;
this.userPW = pw;
}
/*
public void setID(String id){
this.userId = id;
}
public void setPW(String pw){
this.userPW = pw;
}
public String getID(){
return userId;
}
public String getPW(){
return userPW;
}
*/
}
위와 같이 작성하고, 내가 구현한 함수들은 포함되어 있으면 안 된다. 위에 선언한 @Builder에서 생성 관련된 함수들을 내장하고 있고, 조회 관련 함수는 @Getter가 내장하고 있다.
같은 의미로 Setter와 Builder는 생성, 수정 함수가 겹치기 때문에 Setter를 사용하지 않는다.
또, @NoArgsConstructor를 이용해 모든 파라미터가 생성되는 것을 막아준다. 반대로는 @AllArgsConstructor가 있다. 이는 생성자에 모든 파라미터가 기본적으로 생성되는 옵션(?)이다.
위처럼 @NoArgsConstructor를 선언하고, 각 생성자 단위로 @Builder를 선언하면 매개변수로 받아온 파라미터에 대해서만 Builder 연산을 할 수 있다.
나는 로그인과 회원가입에서 같은 class를 사용할 예정이기 때문에 이와 같은 방법을 선택했다.
받아온 객체를 log로 찍어보면 아래와 같은 결과를 확인할 수 있다!

참고자료
useState 관련 - HOOK 알아보기
Builder 패턴 관련 - @Builder, @All/NoArgsConstructor 제대로 알고 사용하자!
로그 찍기 - [Java] 간단한 로깅(Logging) 사용 방법
'Web' 카테고리의 다른 글
API란? (0) | 2024.06.21 |
---|---|
[Spring+React] Session으로 사용자 정보 관리하기 (0) | 2024.04.17 |
[React] 동기와 비동기 / async와 await (0) | 2024.04.15 |
[Spring] CORS 설정으로 오류 해결 (0) | 2024.04.11 |