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,
});
};
[중략 ....]
}
코드상 화면에서는 조회 / 전송 부분만 우선 구현 및 적용시킨 샤례입니다.