본문 바로가기
코딩생활/ReactNative

[React Native] 3-12 달력 기능 구현하기 (2)

by InfoJun 2023. 4. 3.
반응형

이번에는 특정 날짜를 선택했을 때 그날 작성된 로그들을 달력 하단에

 

목록으로 띄워볼 것 입니다.

 

이 때 FeedList를 재사용할 수 있습니다.

 

FeddList를 CalnedarView 하단에 보여주는 것은 아닙니다.

 

FeedList에서 사용한 FlatList에 ListHeaderComponent라는 Props를 사용할 것입니다.

 

components/FeedList.js

import React from 'react';
import {View, StyleSheet, FlatList} from 'react-native';
import FeedListItem from './FeedListItem';

function FeedList({logs, onScrolledToBottom, ListHeaderComponent}) {
 (...)
  return (
    <FlatList
      data={logs}
      style={styles.block}
      renderItem={({item}) => <FeedListItem log={item} />}
      keyExtractor={log => log.id}
      ItemSeparatorComponent={() => <View style={styles.separator} />}
      onScroll={onScroll}
      ListHeaderComponent={ListHeaderComponent}
    />
  );
}
 (...)

 

이 후 CalendarScreen에서 현재 선택된 날짜로 로그를 필터링해서

 

FeedList에 전달하고 ListHeaderComponent에는 CalendarView를 설정합니다.

 

screens/CalendarScreen.js

import React, {useContext, useState} from 'react';
import CalendarView from '../components/CaendarView';
import LogContext from '../contexts/LogContext';
import {format} from 'date-fns';
import FeedList from '../components/FeedList';

function CalendarScreen() {
(...)

  const filteredLogs = logs.filter(
    log => format(new Date(log.date), 'yyyy-MM-dd') === selectDate,
  );

  return (
    <FeedList
      logs={filteredLogs}
      ListHeaderComponent={
        <CalendarView
          markedDates={markedDates}
          selectedDate={selectDate}
          onSelectDate={setSelectDate}
        />
      }
    />
  );
}

export default CalendarScreen;

다음과 같이 선택된 날짜에 글이 나타나는지 확인해보세요.


useMemo Hook로 최적화 하기

현재 이 컴포넌트는 리렌더링 될때마다 markedDates를 생성합니다.

 

날짜가 변경될 때에도 컴포넌트는 리렌더링 되고 있습니다.

 

markedDates는 날짜가 바뀌어도 변하지 않기 때문에 매번 생설할 필요가 없습니다.

 

이러한 상황에서는 useMemo라는 Hook을 사용해 값을 메모이제이션(memoization)하여 최적화할 수 있습니다.

 

메모지제이션이란 동일한 계산을 반복해야 할 때 불필요한 연산을 제거하기 위해

 

이전에 계산한 값을 재사용해 처리를 최적화 하는 것입니다.

 

사용법은 다음과 같습니다.

 

const value = useMemo(() -> compute(a,b),[a,b]);

 

이렇게 Hook을 사용하면 a나 b의 값이 변경될 때만 값이 연산됩니다.

 

screens/CalendarScreen.js

import React, {useContext, useMemo, useState} from 'react';
import CalendarView from '../components/CaendarView';
import LogContext from '../contexts/LogContext';
import {format} from 'date-fns';
import FeedList from '../components/FeedList';

function CalendarScreen() {
  const {logs} = useContext(LogContext);

  const [selectDate, setSelectDate] = useState(
    format(new Date(), 'yyyy-mm-dd'),
  );

  const markedDates = useMemo(
    () =>
      logs.reduce((acc, current) => {
        const formattedDate = format(new Date(current.date), 'yyyy-mm-dd');
        acc[formattedDate] = {marked: true};
        return acc;
      }, {}),
    [logs],
  );
(...)

 

이렇게 하면 logs 배열이 바뀔 때만 logs.reduce함수가 수행됩니다.

반응형

댓글