앱을 개발하다가 현재 페이지에서 useState
로 세팅된 값을 넘겨주어야 할 일이 생겼다.
export default function PaymentResult() {
// ...
return (
<TouchableOpacity
style={[styles.paymentBtn, styles.btn]}
onPress={() => {
if (buyerName === '' || buyerName === null) {
Alert.alert('배송지 정보 누락', '받는 사람의 이름이 입력되지 않았습니다.');
} else if (buyerAddr === '' || buyerAddr === null) {
Alert.alert('배송지 정보 누락','받는 사람의 주소가 입력되지 않았습니다.');
} else if (buyerAddrDetail === '' || buyerAddrDetail === null) {
Alert.alert('배송지 정보 누락','받는 사람의 상세 주소가 입력되지 않았습니다.');
} else if (buyerTel === '' || buyerTel === null) {
Alert.alert('배송지 정보 누락','받는 사람의 연락처가 입력되지 않았습니다.');
} else if (pg === '' || pg === null) {
Alert.alert('결제수단 누락', '결제수단이 선택되지 않았습니다');
} else {
// 모든 정보를 가지고
AsyncStorage.setItem('payment', JSON.stringify({
pg: pg,
pay_method: 'card',
merchant_uid: `ORD-${uid}-userId`, // 사용자 아이디를 추가
name: '카카오 도마 칼 세트',
amount: amount,
buyer_email: 'kakao@kakao.com',
buyer_name: buyerName,
buyer_tel: buyerTel,
buyer_addr: buyerAddr,
buyer_detail_addr: buyerAddrDetail,
buyer_postcode: buyerPostcode,
app_scheme: 'example',
escrow: false
}));
// Payment 컴포넌트로 이동
navigation.navigate('payment');
}
}}
>
<Text>결제하기</Text>
</TouchableOpacity>
)
}
보통 이렇게 AsyncStorage
를 사용하는 방법이 있지만
사용자가 결제를 하지 않고 이전 페이지로 돌아간다고 가정할 때 저대로 놔두면 메모리 누수가 발생하게 된다.
그래서 결제 페이지에서 AsyncStorage
로 넘겨온 값을 지워주기 위해 removeItem
메소드를 사용했다.
export default function Payment({ navigation }:any) {
// 결제시 Iamport Module에 전송할 값을 세팅
const [paymentInform, setPaymentInform] = useState({
// ...
});
// AsyncStorage로 저장해서 받아온 값을 poaymentInfo에 넣어줌.
const getPaymentInform = async () => {
let payInform = await AsyncStorage.getItem('payment');
try {
if (payInform !== null) {
setPaymentInform(JSON.parse(payInform));
// 결제 하지 않고 뒤로 돌아갈 때 메모리 누수 방지
AsyncStorage.removeItem('payment');
}
} catch (err) {
console.log(err);
}
}
getPaymentInform();
// Iamport 모듈 실행에 대한 콜백함수
const callBack = (resp:any) => {
// ...
}
return (
<>
{/* Node Module 설치 확인 필(iamport-react-native) */}
<IMP.Payment
userCode={'imp86589899'}
data={paymentInform}
loading={<Loading />}
callback={callBack}
/>
</>
)
}
결제가 이루어질 때 callback
을 실행해야 하는데, resp
로 넘어온 값 중에 imp_success
가 true
인 경우와 false
인 경우로 나눠서 작업을 처리할 콜백함수가 필요하다.
원래는 nativation.replace()
를 사용해서 페이지 이동을 해주어야 하지만, 위에서 removeItem
을 했기 때문에 AsyncStorage.getItem('payment')
를 사용할 수 없다.
그래서 navigation.navigate()
로 넘겨주는 대신 객체형태로 값을 전달하게 해준다.
// Iamport 모듈 실행에 대한 콜백함수
const callBack = (resp:any) => {
// console.log(resp);
if (resp.imp_success === 'true') {
navigation.navigate('paymentResult', {"key": paymentInform});
//navigation.replace('paymentResult', resp); // 원래 방법
//navigation.navigate('paymentResult', JSON.stringify(paymentInform)); // JSON.stringify로 해도 안됨...
} else {
navigation.replace('paymentFailed', resp);
}
}
결과 화면에서 { route }
가 매개변수로 들어가야하고 route
로 접근해서 params.key
로 빼올 수 있다.
export default function PaymentResult({ navigation, route }:any) {
/*
Payment 컴포넌트에서 Iamport 모듈의 data 속성에 전달해주는 값을 그대로 가져온다.
Payment 컴포넌트에서 사용자가 임의로 결제를 취소하는 경우 메모리 누수가 발생하므로
이를 방지하기 위해 AsyncStorage가 remove되도록 했기 때문에 값을 가져올 수 없다.
이 때 data에 넣어주는 값은 JavaScript 객체이고, 이 값을 PaymentResult로 가져오기 위해
Iamport의 콜백함수에서 navigate 메소드에 data를 전달하는데, key-value 형태로 값을 가져와야 이 컴포넌트에서 불러올 수 있다.
그냥 getter로 전달하려고 했더니 안된다...
*/
const paymentData = route.params.key;
console.log(paymentData);
// 결제 성공시 배송 및 주문 정보를 axios로 백엔드에 넘겨서 처리
useEffect(() => {
axios.post('http://192.168.0.13:3000/payment/addGoodsShoppingList', null,
{
params: {
memberId: paymentData.buyer_name,
paymentPay: paymentData.amount,
paymentMainAddr: paymentData.buyer_addr,
paymentDetailAddr: paymentData.buyer_detail_addr,
paymentZipcode: paymentData.buyer_postcode
}})
.then((res) => console.log(res.data))
.catch((err) => console.log(err));
}, [])
return (
<View style={styles.container}>
<Text style={styles.title}>결제가 완료되었습니다!</Text>
<View style={styles.btnGroup}>
<TouchableOpacity
style={[styles.btn, styles.btnPrimary]}
// onPress={() => navigation.navigate("Home")}
>
<Text style={styles.btnText}>상세 주문 정보</Text>
</TouchableOpacity>
<TouchableOpacity
style={[styles.btn, styles.btnBack]}
onPress={() => navigation.navigate("Home")}
>
<Text style={styles.btnText}>계속 쇼핑하기</Text>
</TouchableOpacity>
</View>
</View>
)
}
'Study > React' 카테고리의 다른 글
[React Native] Modal 사용하기 (0) | 2022.04.05 |
---|---|
[React Native] useEffect의 dependency array 사용 시 주의점 (0) | 2022.04.02 |
[React Native] axios를 사용한 비동기 통신과 장면 전환 (1) | 2022.03.11 |
[React Native] axios를 사용하여 spring boot로 비동기 통신 하기 (0) | 2022.03.10 |
[React Native] 다른 화면으로 전환하기 (0) | 2022.03.09 |