디테일 페이지 이동 후 브라우저 뒤로 가기를 통해 다시 레시피 페이지로 돌아왔을 때, 리렌더링이 발생해 페이지 초기 상태로 돌아옴.
분류와 소팅을 거친 아이템들의 화면 상태로 되돌아가기 위해 필터링 상태, 소팅 상태, 스크롤 상태의 마지막 위치를 기억해야했음.
기존 코드 기록 및 화면 녹화를 하지 못해 개선한 상태의 코드와 gif 파일만 첨부함.
import { useEffect } from 'react';
const useMemoScrollPosition = () => {
useEffect(() => {
const lastScrollTop = Number(sessionStorage.getItem('scroll_top'));
if (lastScrollTop) {
window.scrollTo(0, lastScrollTop);
}
}, []);
useEffect(() => {
return () => {
sessionStorage.setItem('scroll_top', window.scrollY.toString());
};
}, []);
};
export default useMemoScrollPosition;
import { User } from 'firebase/auth';
import { useState } from 'react';
const useRecipeFilters = (
recipeData: Recipe[],
myIngredients: string[],
user: User | null
) => {
const initialCategory = () => {
const savedCategory = sessionStorage.getItem('selected_category_type');
return savedCategory ? savedCategory : '전체 레시피';
};
const [selectedCategory, setSelectedCategory] = useState(initialCategory);
const [sortType, setSortType] = useState<string>(
() => sessionStorage.getItem('selected_sort_type') || '기존 정렬 상태'
);
const handleCategoryType = (changeCategoryType: string) => {
setSelectedCategory(changeCategoryType);
sessionStorage.setItem('selected_category_type', changeCategoryType);
};
const handleSortType = (changeSortType: string) => {
setSortType(changeSortType);
sessionStorage.setItem('selected_sort_type', changeSortType);
};
const canMakeRecipe = (
recipeIngredients: string,
myIngredients: string[]
): boolean => {
return myIngredients.every((ingredient) =>
recipeIngredients.includes(ingredient)
);
};
const filteredRecipes =
selectedCategory && selectedCategory !== '전체 레시피'
? recipeData.filter((recipe: Recipe) => {
if (selectedCategory === '나의 냉장고' && myIngredients.length > 0) {
return canMakeRecipe(recipe.ingredients, myIngredients);
}
return recipe.type === selectedCategory;
})
: recipeData;
const noRecipeMessage =
selectedCategory === '나의 냉장고' && filteredRecipes.length === 0
? user
? '냉장고가 비었거나 냉장고에 보관된 재료들을 전부 포함해서 만들 수 있는 레시피가 없어요. 🫤'
: '로그인 후 냉장고에 재료들을 넣어주세요. 🫤'
: null;
const sortedRecipes = (recipes: Recipe[]): Recipe[] => {
if (sortType === '가나다 순') {
return [...recipes].sort((a: Recipe, b: Recipe) =>
a.name.localeCompare(b.name)
);
} else if (sortType === '저칼로리 순') {
return [...recipes].sort(
(a: Recipe, b: Recipe) => parseFloat(a.calorie) - parseFloat(b.calorie)
);
}
return recipes;
};
return {
selectedCategory,
sortType,
handleCategoryType,
handleSortType,
noRecipeMessage,
sortedRecipes,
filteredRecipes,
};
};
export default useRecipeFilters;
커스텀 훅 코드에 sessionStorage.getItem('selected_sort_type') || '기존 정렬 상태' 등의 코드를 추가해 세션에 필터링, 소팅을 거쳐 나온 상태의 스크롤 위치를 기억하도록 코드를 수정해 기존 레시피 페이지에 훅을 import해서 사용함.
...
useMemoScrollPosition();
...
결과

잘 동작한다 ~_~