관리자 페이지React Query 적용기

jjune095·2022년 3월 24일
0

react-query

목록 보기
1/2

https://velog.io/@jun7867/React-Query%EC%99%80-%EC%83%81%ED%83%9C%EA%B4%80%EB%A6%AC

react-query를 신규 프로젝트에 적용한 경험을 공유하고자 합니다.


기존 프로젝트 store 사용

기존 프로젝트에서는 (Mobx) store에 api 통신 로직이 들어가 있어서 상태 관리를 Client State와 Server State가 혼용되어 있었습니다.

export default class MatchMessageStore {
  @observable isOpen: boolean = false;
  ...
  ...
  
  @action
  AcceptInterview = async (positionSn: number, optionSn: number) => {
    try {
      const { data } = await request({
        method: 'put',
        url: URIs.put_match_interview_accept(positionSn),
        params: { optionSn },
      });
      return data;
    } catch (e) {
      console.error(e);
      throw e;
    }
  }
  
  ...
  ...
 }

위의 코드처럼 Store에 api 로직이 들어가 있어 코드도 길어지고 비슷한 api 로직 반복, api만 사용하는 Component도 통신을 위해 observer를 해주다 보니 속도적인 측면에서도 단점이 있었습니다.

client state / server state 분리

신규 프로젝트에서는 기존에 사용하던 store처럼 사용하는 것이 아니라 client state만 store에 저장하고 api 통신은 react-query를 사용하기로 했습니다.
서버에서 관리되고 사용자 모르게 바뀌는 데이터값들은 잠재적으로 오래된 데이터가 될 가능성이 있고 fetching/updating에 비동기가 필요하기에 react-query를 사용하여 해결하기 적합했습니다.


적용

custom hook 사용

// useAccountHook.ts
const changePassword = async (accountInfo: AccountPasswordRq) => {
  await AccountRepo.changePassword(accountInfo); // axios post
};

export default function useChangePassword() {
  return useMutation((accountInfo: AccountPasswordRq) => changePassword(accountInfo), {
    onSuccess: () => {
      { 
        // success
      }
      RouteUtil.goLoginPage('/login');
    },
    onError: () => {
      // error
    },
  });
}



// Account.tsx
const Account = () => {

const { isError, mutate } = useChangePassword(); // custom hook
...

const handleApply = (data: AccountPasswordRq) => {
  mutate(data, {
    onError: (e: any) => {
      setErrorCode(e.response?.data?.errorCode);
                   },
  });
};

...

mutation을 사용하여 post api 통신을 하였고 제공되는 onSuccess, onError를 활용하였습니다.

https://react-query.tanstack.com/guides/updates-from-mutation-responses#_top
https://react-query.tanstack.com/examples/custom-hooks

const fetchUsers = async (option: FetchUsersOption) => {
  const { data } = await UserRepo.fetchUsers(new UserListRq(option)); // axios get api
  return new UserListVO(data);
};

export default function useUsers(option: UseUserOption) {
  return useQuery(['user', 'filters', option], () => fetchUsers(option));
}


// 사용하려는곳 
  const { data } = useUsers({
    ... // data parameter
  });
    
  // data.~~

결론

Store에서 client, server state를 분리함으로써 Store에 client state만 관리하도록 하여 목적에 맞게 사용함과 동시에 불필요한 상태관리를 피할 수 있었습니다. 또한 error처리, fetching, updating을 react-query를 통해 편리하게 적용할 수 있었습니다.

profile
프론트엔드 개발자 남준영입니다.

0개의 댓글