React query & hook 처리

React query & hook 처리

react query 및 hook 사용했던 내용 기록

·

2 min read

XRP 입출금 개발을 진행하면서 admin에서 작업했던 Frontend (React) 작업 내용을 기록해보고자 합니다.

기존 redux 비지향 하면서 (redux to react-query + recoil 전환) 직접 프론트 개발을 진행하였고 이는 당시 계셨던 프론트엔드 개발자분들과 협의 및 회의를 통해 앞으로는 redux 지양하자라는 결과를 도출 이후 작업했던 내용입니다.

이력

당시 작업했던 이력입니다.

React Hook

import { useInfiniteQuery, useMutation, useQuery } from '@tanstack/react-query';

import {
  getAccountInfo,
  getAccountTx,
  sendAsset,
} from '../../../apis/collectionWallet';
import { SendAssetRequest } from '../../../apis/collectionWallet/types';

/**
 * 집금지갑 정보 조회 (Balance)
 * @param symbol
 */
export const useAccountInfo = (symbol: string) => {
  return useQuery({
    queryKey: [symbol],
    queryFn: () => getAccountInfo({ symbol }).then((ksRes) => ksRes.data),
    enabled: true,
  });
};

/**
 * 지갑 자산 전송
 */
export const useSendAsset = () => {
  return useMutation((params: SendAssetRequest) =>
    sendAsset(params).then((res) => res.data),
  );
};

/**
 * 지갑 infinity query
 * @param symbol
 * @param nextIndex
 * @param pagePerCount
 */
export const useAccountTx = (
  symbol: string,
  nextIndex: number,
  pagePerCount: number,
) => {
  return useInfiniteQuery({
    queryKey: [symbol, nextIndex],
    queryFn: () =>
      getAccountTx({
        symbol,
        nextIndex,
        pagePerCount,
      }).then((res) => res.data),
    enabled: !!(symbol && pagePerCount),
  });
};

총 3가지의 react-query-hook을 사용했으며

useQuery : 단건 조회
useMutation : 데이터 저장
useInfiniteQuery : 리스트 형태에 페이지 네비게이션 처리를 위해 사용

위의 내용과 같이 관련 목적에 따라 Hook을 생성하였습니다.

화면 코드

xport const WalletInfoComponent: FC<WalletInfoComponentProp> = ({
  symbol,
}: WalletInfoComponentProp) => {
  // ########### variable
  const [isLoading, setLoading] = useState<boolean>(true);
  const [addressInfo, setAddressInfo] = useState<
    CollectionWalletInfoResponse | undefined
  >(undefined);
  const [toAddress, setToAddress] = useState<string>(``);
  const [tag, setTag] = useState<string | undefined>(undefined);
  const [unit, setUnit] = useState<Unit>(Unit.eth);
  const [amount, setAmount] = useState<string>(``);
  const { openModal } = useModal();
  const useAccountInfoRes = useAccountInfo(symbol);

  const onSuccess = (result: SendAssetResponse) => {
    openModal(`LargeOneBtnModal`, {
      explanation: (
        <div style={{ textAlign: `left` }}>
          <strong>전송결과:</strong> {result?.status} <br />
          <strong>hash:</strong> {result?.txHash} <br />
          <strong>to:</strong> {result?.to} <br />
          <strong>from:</strong> {result?.from} <br />
          <strong>amount:</strong>
          {` `}
          {convertWeiToEther(result.amount || `0`, true)} <br />
        </div>
      ),
      onConfirm: () => setTimeout(() => useAccountInfoRes.refetch(), 2000), // 네트워크에서 바로 안되서 ㅎㅎ
    });
  };

  const sendAssetMutation = useSendAsset();

  // ####### funtion
  useEffect(() => {
    if (!useAccountInfoRes.isLoading) {
      setLoading(useAccountInfoRes.isLoading);
      setAddressInfo(useAccountInfoRes?.data);
    }
  }, [useAccountInfoRes, setLoading, setAddressInfo]);

  const send = () => {
    const param: SendAssetRequest = {
      symbol,
      toAddress,
      tag,
      amount,
      unit: Unit[unit],
    };
    sendAssetMutation.mutate(param, {
      onSuccess,
      onError: () => {
        openModal(`OneBtn`, {
          explanation: <>전송에 실패하였습니다.</>,
        });
      },
    });
  };
  const onSubmit = () => {
    if (toAddress === `` || amount === ``) {
      openModal(`OneBtn`, {
        explanation: <>입력한 정보를 확인해 주세요</>,
      });
      return;
    }

    openModal(`TwoBtn`, {
      explanation: <>전송하시겠습니까?</>,
      onConfirm: send,
    });
  };

  [중략 ....]
}

코드상 화면에서는 조회 / 전송 부분만 우선 구현 및 적용시킨 샤례입니다.