정수님이 예쁘게 리팩토링을 도와주었다!
먼저 이렇게 배열을 랜덤하게 하는 메소드 자체가 자바스크립트가 없고 앞으로도 쓸 일이 있을 수 있으니까 공통 유틸로 따로 분리를 했다.
// eslint-disable-next-line import/prefer-default-export
export const shuffleArr = <T>(originArr: T[]) => {
const randomArr = originArr.slice();
for (let idx = originArr.length - 1; idx > 0; idx -= 1) {
const randomIdx = Math.floor(Math.random() * (idx + 1));
const temp = randomArr[idx];
randomArr[idx] = randomArr[randomIdx];
randomArr[randomIdx] = temp;
}
return randomArr;
};
그리고 아래와 같이 리팩토링 해서 훨씬 깔끔해짐!
나는 배열에서 고유인덱스를 뽑아낸 배열을 랜덤 시킨 다음에 그 값으로 다시 원래 배열에서 맞는 고유인덱스의 객체를 갖고 왔었는데 유틸로 분리해버리니까 객체가 배열의 원소인 것도 랜덤시킬 수 있더라고.
원래 안 되던 이유가 반복문을 기반으로 해서 쓰는 함수들은(반복문, 고차함수 등) 받는 배열 자체를 그 당시에 수정할 수는 없으니까 고유인덱스 값을 뽑았던 거였는데 shuffleArr로 분리시켰더니 안에서 randomArr로 배열을 복사하고는 걔를 바꾸는 거여서 동작하기 때문이었다.
const revisedThemeGoodsData = useMemo(() => {
const originProduct = data?.originBestProductInfo;
if (originProduct?.length) {
originProduct[0].menus = shuffleArr<Menu>(originProduct[0]?.menus || []);
}
const themeGoods = [...(data?.autoThemeGoods || []), ...(data?.originBestProductInfo || [])];
themeGoods.sort((current, next) => {
const isNeedSwitch =
themeGoodsTypePosition.indexOf(current.themeGoodsType) > themeGoodsTypePosition.indexOf(next.themeGoodsType);
return isNeedSwitch ? 1 : -1;
});
return themeGoods;
}, [data]);