본문 바로가기
React

React(81) 동시접속시 한쪽이 취소하면, 다른한쪽의 버튼 막기

by 새발개발JA 2022. 8. 21.
반응형

 

 

 

두 회원이 중고제품을 거래중이라고 가정해보자.

거래를 하는데 판매자가 거래취소를 하게되면

실시간으로 구매자가 결제를 하지 못하게 막아야 불상사가 일어나지 않는다.

이런 막중한 책임감을 가지고 후덜덜하면서 짯던 코드를 공부용으로 다시 정리해보았다.

 

판매자

  • [취소하기] 버튼을 누르면 취소상태가 된다.

 

구매자

  • 취소상태가 되면 즉시 [결제하기] 을 버튼을 막아야함

 

 

결과화면 미리보기

판매자 아이디로 접속해 있을 때 [취소하기] 버튼을 누르면

 

구매자 화면에서는 [결제하기] 를 누르면  결제 버튼이 활성화비활성화 된다.

활성화에서
비활성화로 바뀐다

 


React(81) 동시접속시 한쪽이 취소하면, 다른한쪽의 버튼 막기

 

payment 타입과 상태 변수

// 페이 진행상황을 타입으로 정리해보았다. 
type PayStatusType = 'start' | 'process' | 'done' | 'cancel';

// 초기 값은 start 로 해주자 
const [payStatus, setPayStatus] = useState<PayStatusType>('start');

 

 

payment 상태를 감시하는 useEffect 

  // payStatus 가 변경될 때마다 useEffect 는 감지하여 api를 get 해온다
  useEffect(() => {
    if (payID) return;

    getPayment(payID); 
  }, [payID, payStatus]); // payID 나 payStatus가 변경되면 호출

 

 

payment 정보를 가져오는 로직

    async function getPayment(payID: string) {
      try {
        const res = await http.get(
		  `${apiAddress}/${payID}` // http 통신으로 payID를 파람으로 받는 api를 호출한다
        );

        if (res.data.resultData) {
          const payInfo: PayInfo = JSON.parse( // payInfo 변수안에 받아온 데이터를 저어장
            JSON.stringify(res.data.resultData)
          );
          
          if (!payInfo) {
            throw new Error(`PayInfo is not exist`); // 에러시 예외처리도 빈틈없이!
          }

          setPayInfo(payInfo); 		   // useState 변수에 저장해주자
          setPayStatus(payInfo.payStatus); // 결제 상태만 따로 빼서 저장해주었다.
        }
      } catch (e) {
          alert('정보를 가져오지 못했습니다.');
          history.push('/'); 		   // 에러가 나면 메인 페이지로 돌아가기 
      }
    }

 

취소버튼 누르면 실행되는 함수

async function updatePayment(payID: string, status: PayStatusType) {
    try {
      const res = await http.put( // 업데이트 쳐준다
        `${apiAddress}/${payID}`,
        { status: state }
      );
      
      setPayStatus(status);       // 내부변수에 상태를 저장해주자
    } catch {
          alert('정보를 가져오지 못했습니다.');
    }
  }

 

 

결제버튼 누르면 실행되는 함수 

async function goToPaymentPage() {
    if (!payID) return;

    if (payStatus === 'cancel') { // 취소상태면 실행되지 않도록 막아주자
      alert('거래가 취소되어 결제가 불가능합니다.');
      return;
    }

    window.location.replace(
      `/payment?payID=${payID}`
    );
  }

 

취소버튼

<button
  className="cancel-btn"
  onClick={() => updatePayment('cancel')}
>
  취소
</button>

 

결제버튼

<button
  className={`pay-btn ${ payStatus === 'cancel' ? 'diable' : ''}`}
  onClick={goToPaymentPage}
>
  결제하기
</button>

 

 

 

 

 

 

 

 

 

반응형

댓글