프로젝트를 진행하면서 상위 컴포넌트가 useState로 떡칠되는 상황을 마주했다...
그러다가 개발바닥 유튜브의 호돌맨님이 valtio
를 사용하는 것을 보고 이것을 적용 시켜보기로 했다.
React에서 proxy기반의 상태(반응형)관리 해주는 라이브러리.
간단하게 설명하자면 대리라는 의미의 영단어 이다.
두 개 이상의 서버가 서로 통신을 주고 받을 때 그 사이에서 대리해주는, 중계해주는 것을 proxy라고 하며, 이 서버를 proxy 서버라고 한다.
❓valtio는 중계서버를 이용해서 상태를 관리하는 것 같다. 정확한건 더 공부해봐야 할 것 같다.
npm i valtio
로 다운받아주면 된다
github valtio 의 예제와 호돌맨님의 예제를 통해 연습해봤다..
import { proxy, useSnapshot } from 'valtio'
class User {
public id = kim
public name = 'jaehan'
public changeName(name: string) {
this.name = name
}
}
const state = proxy<User>(new User())
export default function () {
const snap = useSnapshot(user)
return (
<div>
<p>{snap.id}</p>
<p>{snap.name}</p>
<button onClick={()=>state.changeName('재한')}>
이름변경
</button>
</div>
);
}
호돌맨 님은 따로 user class를 만들어서 proxy에 넣어주어서 만들길래 한번 따라해 봤다.
📌 github 예제를 보면 proxy를 넣어준 state 변수는 값을 변경하는 상황이 왔을때 사용하고
📌 useSnapshot을 넣어준 snap은 변경사항을 포착하는 읽기 전용 변수여서 읽을 때만 사용한다고 나와있다.
우리 프로젝트의 회원가입 페이지에 이메일, 비밀번호, 이름... 등등 다 useState로 떡칠 되어있었는데 valtio를 적용하는 refactoring을 진행해봤다.
우선 class를 지정해줄 entity 폴더를 만들고 user class를 추가했다.
entity/User.ts
export default class UserEntity {
email = '';
username = '';
password = '';
phoneNumber = '';
role = '';
emailValid = true;
phoneNumValid = true;
checkEmailValid() {
this.emailValid =
/^[0-9a-zA-Z]([-_\.]?[0-9a-zA-Z])*@[0-9a-zA-Z]([-_\.]?[0-9a-zA-Z])*\.[a-zA-Z]{2,3}$/.test(
this.email
);
}
checkPhoneNumValid() {
this.phoneNumValid = /^01(?:0|1|[6-9])-(?:\d{3}|\d{4})-\d{4}$/.test(
this.phoneNumber
);
}
emailValidMessage() {
return this.emailValid ? '' : 'Not a valid email address';
}
phoneNumValidMessage() {
return this.phoneNumValid ? '' : 'Not a valid phone number';
}
}
page/signup.tsx
const state = proxy<UserEntity>(new UserEntity());
export const SignUp = () => {
const snap = useSnapshot(state);
const handlePassword = (e: ChangeEvent<HTMLInputElement>) =>
(state.password = e.target.value);
...
}
❓ onChange handler도 class 안에 넣어주고 싶은데 이게 왜 잘 안되는지는 더 찾아봐야겠다.