FeedListItem 컴포넌트 만들기
먼저 FeedListItem 컴포넌트를 만들어야 합니다.
이 컴포넌트는 log 객체를 Props로 받아와서 알맞은 위치에 보여줄 것 입니다.
글 목록에서 화면에 body를 보여줄 때는 전체 내용을 보여주지 않습니다.
줄 바꿈 문자를 모두 없애야하고, 길이가 100자 이상이면 줄임표를 사용해야합니다.
이런 작업을 하는 truncate라는 함수도 따로 선언해주겠습니다.
그리고 추후 이 항목을 선택하려면 WriteScreen을 다시 띄워서 전체 내용을 볼 수 있게 해줘야 하기 때문에
Pressable 컴포넌트도 사용할 것입니다.
components/FeedListItem.js
import React from 'react';
import {Platform, Pressable, StyleSheet, Text} from 'react-native';
function truncate(text) {
//정규식을 사용해 모든 줄 바꿈 문자 제거
const replaced = text.replace(/\n/g, ' ');
if (replaced.length <= 100) {
return replaced;
}
return replaced.slice(0, 100).concat('...');
}
function FeedListItem({log}) {
const {title, body, date} = log;
return (
<Pressable
style={pressed => [
styles.block,
Platform.OS === 'ios' && pressed && {backgroundColor: '#efefef'},
]}
android_ripple={{color: '#ededed'}}>
<Text style={styles.date}>{new Date(date).toLocaleDateString()}</Text>
<Text style={styles.title}>{title}</Text>
<Text style={styles.body}>{truncate(body)}</Text>
</Pressable>
);
}
const styles = StyleSheet.create({
block: {
backgroundColor: 'white',
paddingHorizontal: 16,
paddingVertical: 24,
},
date: {
fontSize: 12,
color: '#546e7a',
marginBottom: 8,
},
title: {
color: '#263238',
fontSize: 18,
fontWeight: 'bold',
marginBottom: 8,
},
body: {
color: '#37474f',
fontSize: 16,
lineHeight: 21,
},
});
export default FeedListItem;
FeedList 컴포넌트 만들기
이번엔 FeedList 컴포넌트를 만들 것입니다.
이 컴포넌트는 logs라는 Props를 받아와서 FlatList를 통해 여러 항목을 보여줄 것입니다.
FeedsScreen에서 FlatList를 바로 사용하지 않고 FeedList 컴포넌트를 따로 만드는 이유는
추후 달력 화면에서 재활용할 것이기 때문입니다.
components/FeedList.js
import React from 'react';
import {View, StyleSheet, FlatList} from 'react-native';
import FeedListItem from './FeedListItem';
function FeedList({logs}) {
return (
<FeedList
data={logs}
style={styles.block}
renderItem={({item}) => <FeedListItem log={item} />}
keyExtractor={log => log.id}
ItemSeparatorComponent={() => <View style={styles.separator} />}
/>
);
}
const styles = StyleSheet.create({
block: {flex: 1},
separator: {
backgroundColor: '#e0e0e0',
height: 1,
width: '100%',
},
});
export default FeedList;
이후 사용해보겠습니다.
screens/FeedsScreen.js
import React, {useContext} from 'react';
import {View, StyleSheet, TextInput} from 'react-native';
import LogContext from '../contexts/LogContext';
import FloatingWriteButton from '../components/FloatingWriteButton';
import FeedList from '../components/FeedList';
function FeedsScreen() {
const {logs} = useContext(LogContext);
return (
<View style={styles.block}>
<FeedList logs={logs} /> //추가
<FloatingWriteButton />
</View>
);
}
const styles = StyleSheet.create({
block: {
flex: 1,
},
});
export default FeedsScreen;
새 로그를 작성하여 잘 나타나는지 확인해보세요.
date-fns로 날짜 포맷팅하기
현재 FeedListItem에서 시간을 보여줄 때 Date 객채의 toLocaleString()을 사용하고있는데
작성 시간에 따라 다음과 같은 형식으로 보이게 하겠습니다.
- 방금 전
- 3분 전
- 1시간 전
- 3일 전
- 2023년 3월 15일 07:00
이 때 유용하게 사용할 수 있는 라이브러리가 date-fns 입니다.
$ yarn add date-fns
다음 라이브러리에서 불러와 사용할 함수는 다음과 같습니다.
- fromatDistanceTonow : 현재 시각을 기준으로 단어를 사용해 시간을 나타냅니다.(ex : 5분전)
- format : 다양한 형태로 날짜를 포맷팅합니다
components/FeedListItem.js
import React from 'react';
import {Platform, Pressable, StyleSheet, Text, View} from 'react-native';
import {format, formatDistanceToNow} from 'date-fns';
import {ko} from 'date-fns/locale';
function formatDate(date) {
const d = new Date(date);
const now = Date.now();
const diff = (now - d.getTime()) / 1000;
if (diff < 60 * 1) {
return '방금 전';
}
if (diff < 60 * 60 * 24 * 3) {
return formatDistanceToNow(d, {addSuffix: true});
}
return format(d, 'PPP EEE p');
}
function truncate(text) {
// 정규식을 사용해 모든 줄 바꿈 문자 제거
const replaced = text.replace(/\n/g, ' ');
if (replaced.length <= 100) {
return replaced;
}
return replaced.slice(0, 100).concat('...');
}
function FeedListItem({log}) {
const {title, body, date} = log; // 사용하기 편하게 객체 구조 분해 할당
return (
<Pressable
style={({pressed}) => [
styles.block,
Platform.OS === 'ios' && pressed && {backgroundColor: '#efefef'},
]}
android_ripple={{color: '#ededed'}}>
<Text style={styles.date}>{formatDate(date)}</Text>
<Text style={styles.title}>{title}</Text>
<Text style={styles.body}>{truncate(body)}</Text>
</Pressable>
);
}
const styles = StyleSheet.create({
block: {
backgroundColor: 'white',
paddingHorizontal: 16,
paddingVertical: 24,
},
date: {
fontSize: 12,
color: '#546e7a',
marginBottom: 8,
},
title: {
color: '#263238',
fontSize: 18,
fontWeight: 'bold',
marginBottom: 8,
},
body: {
color: '#37474f',
fontSize: 16,
lineHeight: 21,
},
});
export default FeedListItem;
현재 이유는 모르겠는데 locale: ko를 쓰면 자꾸 오류가 난다..
글 작성하다가 이건 왜 나는걸까를 찾을 수가 없다..
혹시 아는사람,,
'코딩생활 > ReactNative' 카테고리의 다른 글
[React Native] 3-8 스크롤 내렸을 때 글쓰기 버튼 숨기기 (0) | 2023.03.18 |
---|---|
[React Native] 3-7 Animated로 애니메이션 적용 (0) | 2023.03.17 |
[React Native] 3-6 LogContext로 배열 상태 관리하기 (0) | 2023.03.15 |
[React Native] 3-4 WriteScreen 준비하기 (0) | 2023.03.14 |
[React Native] 3-4 새 글 작성하기 (0) | 2023.03.14 |
댓글