valtio 사용법

jaehan·2022년 8월 18일
3

React

목록 보기
13/33
post-thumbnail
post-custom-banner

프로젝트를 진행하면서 상위 컴포넌트가 useState로 떡칠되는 상황을 마주했다...

그러다가 개발바닥 유튜브의 호돌맨님이 valtio를 사용하는 것을 보고 이것을 적용 시켜보기로 했다.

valtio

React에서 proxy기반의 상태(반응형)관리 해주는 라이브러리.

proxy 란?

간단하게 설명하자면 대리라는 의미의 영단어 이다.

두 개 이상의 서버가 서로 통신을 주고 받을 때 그 사이에서 대리해주는, 중계해주는 것을 proxy라고 하며, 이 서버를 proxy 서버라고 한다.

❓valtio는 중계서버를 이용해서 상태를 관리하는 것 같다. 정확한건 더 공부해봐야 할 것 같다.

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은 변경사항을 포착하는 읽기 전용 변수여서 읽을 때만 사용한다고 나와있다.

valtio 적용

우리 프로젝트의 회원가입 페이지에 이메일, 비밀번호, 이름... 등등 다 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 안에 넣어주고 싶은데 이게 왜 잘 안되는지는 더 찾아봐야겠다.

post-custom-banner

0개의 댓글