전문가 의뢰 메인페이지에서 posts와 filteredPosts가 있는데 결론적으로는 filteredPosts만 사용하고 있었다. 같은 데이터를 두 개로 관리하면 실수를 할 가능성이 높아진다는 피드백을 받고 기존 코드를 수정해서 filteredPosts만 상태관리를 하도록 수정했다.
fetchData()
비동기 함수로 특정 페이지와 언이 필터링 조건에 따라 데이터를 가져옴
langQuery
: 선택된 언어가 있으면 쿼리 문자열에 추가
url
: 데이터를 가져올 API 엔드포인트
response
&data
: 데이터를 가져와 JSON 형식으로 파싱- 데이터를 가져와 posts와 filteredPosts 상태를 업데이트
- page 또는 selectedLanguages가 변경될 때 마다
fetchData()
함수를 호출하여 데이터를 다시 가져옴
- selectedLanguages또는 posts가 변경될 때 마다 필터링된 게시물 리스트를 업데이트함
선택된 언어가 있을 경우, 해당 언어에 맞는 게시물만 필터링하여 filteredPosts 상태를 업데이트함
선택된 언어가 없을 경우, 전체 게시물을 filteredPosts에 저장함
- 사용자가 페이지를 스크롤하여 거의 끝에 도달했을때, 다음 페이지의 데이터를 로드함 ( 무한 스크롤 )
handleScroll
함수가 스크롤 이벤트를 감지하고 조건이 맞으면 페이지 번호를 증가시킴
handleLanguageFilter
함수는 선택된 언어를 업데이트하고, 해당 언어로 데이터를 다시 로드함
선택된 언어가 이미 리스트에 있는 경우, 리스트에서 제거
선택된 언어가 리스트에 없는 경우, 리스트에 추가
페이지 번호를 0으로 리셋하고, 새로 선택된 언어에 맞게 데이터를 다시 가져옴
- 데이터를 불러와서 상태를 업데이트 하는 방식은 동일하지만
filteredPosts
의 상태만 업데이트함- 사용자가 페이지를 스크롤하여 거의 끝에 도달했을때
loading
상태를true
로 변경loading
상태가true
로 변경되었을때 데이터를 가져오는 로직을 처리함handleLanguageFilter
함수는 선택된 언어를 업데이트하고, 해당 언어로 데이터를 다시 로드함
기존 코드에서 fetchData()
가 컴포넌트가 렌더링 될 때 마다 새로 생성되고 있었다. 성능 최적화를 위해 useEffect내부 또는 컴포넌트 외부에 선언하는것이 좋다고 피드백을 받아서 개선했다
const fetchData = async (page: number, languages: string[] = []) => {
try {
const langQuery = languages.length > 0 ? `&languages=${encodeURIComponent(JSON.stringify(languages))}` : '';
const url = `/api/proMain?page=${page}${langQuery}`;
const response = await fetch(url);
const data = await response.json();
if (data && Array.isArray(data)) {
if (page === 0) {
setFilteredPosts(data);
} else {
setFilteredPosts((prevPosts) => [...prevPosts, ...data]);
}
} else {
console.error('data fetch error');
}
} catch (error) {
console.error(error);
}
};
피드백을 받고 useEffect 내부에서 선언을 하려고 했는데 그럴 경우 코드의 재사용성이 낮아질 수 있을것 같다는 생각을 했다.
그래서 fetchData
함수를 useCallback()
함수로 감싸 주기로 결정을 했다
const fetchData = useCallback(async (page: number, languages: string[] = []) => {
try {
const langQuery = languages.length > 0 ? `&languages=${encodeURIComponent(JSON.stringify(languages))}` : '';
const url = `/api/proMain?page=${page}${langQuery}`;
const response = await fetch(url);
const data = await response.json();
if (data && Array.isArray(data)) {
if (page === 0) {
setFilteredPosts(data);
} else {
setFilteredPosts((prevPosts) => [...prevPosts, ...data]);
}
} else {
console.error('data fetch error');
}
} catch (error) {
console.error(error);
}
}, []);