// 렌더 부분
<ProductDetailHeader goBack={goBack} />
<ProductDetailTab goToSelectProduct={goToSelectProduct} />
<Stack.Screen
name='productDetail'
component={ProductDetail}
options={{
title: '제품상세',
headerShown: false,
}}
/>
const ProductDetailHeader = (props) => {
return (
<>
<StatusBar barStyle='dark-content' />
<StyledStatusBar />
<ViewContainer>
<StyledTouchableOpacity>
<AntDesign name='left' size={20} onPress={props.goBack} />
</StyledTouchableOpacity>
<HeaderName>{props.state.name}</HeaderName>
</ViewContainer>
</>
);
};
productDetail
의 헤더ProductDetailHeader
는 모든 스택에서 재활용해서 사용하기 위해 만들어둔 헤더(아래)와는 다르게 Redux state에서 상품명을 가져오고 있다.const StackHeader = (props) => {
return (
<>
<StatusBar barStyle='dark-content' />
<StyledStatusBar />
<ViewContainer>
<StyledTouchableOpacity>
<AntDesign name='left' size={20} onPress={props.goBack} />
</StyledTouchableOpacity>
<HeaderName>{props.title}</HeaderName>
</ViewContainer>
</>
);
};
export default function ProductDetailTab(props) {
return (
<>
<TabStack.Navigator
initialRouteName={'상품설명'}
tabBarOptions={{
activeTintColor: Theme.colors.mainColor,
inactiveTintColor: Theme.colors.grayColor,
pressColor: Theme.colors.mainColor,
indicatorStyle: {
borderBottomWidth: 2,
borderBottomColor: Theme.colors.mainColor,
},
style: {
borderBottomColor: '#d8d8d8',
borderBottomWidth: 0.5,
},
labelStyle: { width: 100 },
}}>
<TabStack.Screen name='상품설명' component={ProductInformation} />
<TabStack.Screen name='상품이미지' component={ProductImage} />
<TabStack.Screen name='상세정보' component={ProductDescription} />
<TabStack.Screen name='구매후기' component={ProductReview} />
<TabStack.Screen name='상품문의' component={ProductInquire} />
</TabStack.Navigator>
<ViewContainer>
<BuyButtonBox onPress={props.goToSelectProduct}>
<BuyButtonText>구매하기</BuyButtonText>
</BuyButtonBox>
</ViewContainer>
</>
);
}
{discountPrice.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',')}
: Detail 페이지의 탭들 중 후기 작성은 재미있는 라이브러리들이 많다.
import * as ImagePicker from 'expo-image-picker';
ImagePicker
이다. 이미지를 첨부할때 사용되는 라이브러리이다. const pickImage = async () => {
let result = await ImagePicker.launchImageLibraryAsync({
mediaTypes: ImagePicker.MediaTypeOptions.All,
allowsEditing: true,
aspect: [4, 3],
quality: 1,
});
if (!result.cancelled) {
const prevImage = [...addImage];
prevImage.push(result.uri);
setAddImage(prevImage);
}
};
const currentDate = () => {
setDate(new Date().toString());
};
: ProductReview page(리스트)
에서 후기 작성에서 작성한 내용을 볼 수 있는 페이지이다.
: 문의하기 기능이 있는 페이지인데 이메일 전송 라이브러리를 사용했다.
import * as MailComposer from 'expo-mail-composer';
expo-mail-composer
는 이메일 보내기가 가능한 라이브러리이다. const handleEmail = () => {
MailComposer.composeAsync({
recipients: ['kaaiinn4@gmail.com'],
subject: title,
body: bodyText,
});
};
: 하단 탭의 두번째 씬이다. 사실 큰 기능은 없다. 그치만 꼭 만들어보고 싶었다.
(카트, 검색기능 등등은 이전 프로젝트에도 많이 있으므로 생략)
Bottom에 존재하는 5개의 탭, 홈에 있는 5개의 탭, 상세 페이지에 있는 5개의 탭, 그리고 장바구니와 같은 10종류 이상의 스택 스크린 페이지까지 정말 수 많은 스택을 네스팅 구조를 결정하는 것에 가장 많은 고민을 했었다. Bottom 탭을 메인 네비게이터로 만드는 실패로 일주일 이상의 시간을 소비하기도 했다.
하지만, 덕분에 이제는 스택 구조화에는 어느 누구보다 자신감이 생겼다.
인턴쉽 기간에 동시에 진행한 프로젝트였다. 때문에 기간 내 모든 시간을 이 프로젝트에 투자하지 못했고 개인적으로 조금 더 완성도 높이지 못한 아쉬움이 있었다. 하지만 동시에 여러개의 프로젝트를 진행 해보는 경험이 추후 협업에 큰 도움이 될 것 같다.
발표때 진짜 보고 깜짝 놀랐어요 상혁님거 코드 보고 리네 공부 좀 하겠읍니다