useCallback 문법
const cachedFn = useCallback(fn, dependencies)
const onToggleSelect = useCallback((id: CountryWithIsSelected["id"]): void => {
setCountryInfos((prev) =>
prev.map((country) =>
country.id === id
? { ...country, isSelected: !country.isSelected }
: country
)
);
const isSelectedCountry = selectedCountries.find((country) => country.id === id);
if (!isSelectedCountry) {
const selectedCountry = countryInfos.find((country) => country.id === id);
if (selectedCountry) {
insertData(selectedCountry);
}
setSelectedCountries((prev) =>
selectedCountry ? [...prev, selectedCountry] : prev
);
} else {
const selectedCountry = selectedCountries.find((country) => country.id === id);
if (selectedCountry) {
deleteData(selectedCountry);
}
setSelectedCountries((prev) => prev.filter((country) => country.id !== id));
}
}, [countryInfos, selectedCountries]);
const sortCountries = useCallback(
(sortOption: string): void => {
setCountryInfos((prev) => {
const newArr = [...prev];
switch (sortOption) {
case "A-Z":
newArr.sort((a, b) => a.countryName.localeCompare(b.countryName));
break;
case "Z-A":
newArr.sort((a, b) => b.countryName.localeCompare(a.countryName));
break;
case "Default":
return [...countryInfos];
default:
return prev;
}
return newArr;
});
},
[countryInfos]
);
const [filteredCountries, setFilteredCountries] = useState<CountryWithIsSelected[]>([]);
.
.
.
useEffect(() => {
const selectedCountryIds = new Set(
selectedCountries.map((country) => country.id)
);
const filtered = countryInfos.filter(
(country) => !selectedCountryIds.has(country.id)
);
setFilteredCountries(filtered);
}, [countryInfos, selectedCountries]);
코드를 최적화하는 과정에서 기존에는 문제가 없던 initialCountryInfos가 데이터를 받아오지 못해 빈 배열로 유지되어 Default 버튼이 제대로 작동하지 않는 문제가 생겼다. 비동기 오류라고 예상했고, 따라서 api에서 데이터를 가져오는 기존 로직을 일부 수정해줬다.
useEffect(() => {
initialCountryInfos = [...countryInfos];
}, [countryInfos]);
이전 코드에서는 데이터를 가져와서 setCountryInfos를 해주면서 initialCountryInfos에 각 countryInfo각 요소를 push해줬지만, 이 로직이 데이터를 가져올 때마다 실행되는 부분이 비효율적이라고 생각되어 따로 useEffect로 빼주어 initialCountryInfos를 업데이트해주는 방식으로 수정했다.
그리고 fetchCountryData함수가 있는 useEffect에 의존 배열로 countryInfos를 추가해 initialCountryInfos가 데이터를 가져온 이후에 제대로 업데이트될 수 있도록 했다.
현재 로직에서 정렬 버튼을 누를 때마다 api가 호출되면서 데이터를 다시 불러오는데 이런 부분은 어떻게 수정할 수 있는지 아직 해결 방법을 찾지 못했다.
하지만 우선 default버튼을 별도로 로직을 설정해줘야한다는 점이 기획 상에서 맞지 않는 부분이라 이 부분에 대한 이해를 하고 넘어가야할 것 같다.