인프런 커뮤니티 질문&답변

ding-co님의 프로필 이미지
ding-co

작성한 질문수

[React / VanillaJS] UI 요소 직접 만들기 Part 1

스크롤박스 (1/2) 리액트 버전

무한스크롤 강의 관련 질문입니다.

해결된 질문

작성

·

235

·

수정됨

0

export const randomize = ({
  min = 0,
  max = 0,
  step = 1,
}: {
  min: number;
  max: number;
  step: number;
}) => {
  if (max < min || max - min < step) throw Error('wrong arguments');
  const num = Math.random() * (max - min) + min;
  return Math.max(Math.floor(num / step) * step, min);
};

1. src/service/util.ts 파일에서 randomize 함수를 보면 위와 같습니다.
num 값을 구하는 표현식이 min 이상 max 이하가 되려면 다음과 같이 바뀌어야 할 것 같습니다.
const num = Math.floor(Math.random() * (max - min + 1)) + min;

 

-> const num = Math.floor(Math.random() * (max - min + 1) + min)


export type Datum = {
  index: number;
  id: string;
  title: string;
  description: string;
};
export type FetchState = 'loading' | 'fetched' | 'idle' | 'error';
export type State<T> = {
  data: T[][];
  state: 'loading' | 'fetched' | 'idle' | 'error';
};
  1. src/components/07_infiniteScroll/vanilla/infiniteFetcher.ts 에서 FetchState 타입을 활용하여 리팩토링 할 수 있을 것 같습니다.
    export type State<T> = { data: T[][]; state: FetchState; };

 

답변 1

1

정재남님의 프로필 이미지
정재남
지식공유자

  1. 당시 step을 적용하다보니 로직이 꼬였었는데요,
    [복습스터디 #3. 무한스크롤 - 코드리뷰 + QnA + 버그수정] 24:30쯤부터
    내용 설명 및 버그 수정하는 내용이 나옵니다.

     

 

  1. 어떤것을 리팩토링하신다는 것인지 이해하지 못했습니다만,
    ding-co님께서 더 나은 방법이라고 생각하시는 코드가 있다면
    수정된 내용 전반을 여기에 공유해주세요.
    다른 분들께도 참고가 되어 좋을 것 같네요!

    참고로 긴 코드는 </> 우측의 [<>] 버튼을 눌러 작성하실 수 있어요.

    image

ding-co님의 프로필 이미지
ding-co
질문자

코드블럭을 다 이용해서 질문을 올렸었는데 최종적으로 올라간 것이 다 깨졌네요.
가독성 좋게 질문 글을 수정해서 올렸습니다.

1번에 대한 질문은 랜덤으로 생성한 숫자가 min 이상 max 이하가 되도록 만드는 로직 수정이며
2번은 그저 타입 alias 재활용입니다.

정재남님의 프로필 이미지
정재남
지식공유자

복습스터디 영상에서 수정한 코드에도 여전히 문제가 있는걸까 싶어 확인해보니
max값에 대한 처리가 안되고 있었네요. 이하가 아닌 미만으로만 동작하고 있었군요 ㅠ

ding-co님께서 작성해주신 코드도 살펴봤는데,
엣지케이스에서 정상적으로 동작하는 것 같긴 합니다.
다만 어떤 이유에서 1을 더해줬다가 floor를 적용하신 건지
수학적 원리를 유추하기가 어렵네요.

하여 제 원 코드를 바탕으로 max값이 등장할 수 있도록 바꿔보자면,
마지막의 floorround로 바꾸면 되는 것 같아요.

const num = Math.random() * (max - min) + min
return Math.max(Math.round(num / step) * step, min)

여기에 안전장치 차원에서 Math.min을 추가해줘도 좋겠네요.

return Math.min(Math.max(Math.round(num / step) * step, min), max)

 

ding-co님의 프로필 이미지
ding-co
질문자

아 제가 말씀드린건 num이 min이상 max 이하의 값이 되기 위해서 표현식만 바꾼 것입니다.
강의 중간에 주석으로 // min <= num <= max 가 있어서
const num = Math.random() * (max - min) + min;
현재 표현식에서는 min이 1, max가 10이라고 하면 1.0이상 10.0 미만이 되기 때문입니다.

그래서 다음과 같은 표현식으로 min <= num <= max 에 해당하는 랜덤 num을 얻을 수 있습니다. max - min 에서 1을 더한 상태에서 floor 내림을 하면 0이상 9이하로 떨어지므로 거기에서 min을 더하면 1이상 10이하가 되기 때문입니다.
const num = Math.floor(Math.random() * (max - min + 1)) + min;

물론 return 할 때 여러 처리를 해주고 적정 random 한 값을 주기 때문에 큰 문제는 없을 것 같습니다~
감사합니다.

정재남님의 프로필 이미지
정재남
지식공유자

// max: 10, min: 2 라고 하면

Math.random()                   // = 0 ~ 0.9999...
max - min + 1                   // = 10 - 2 + 1 = 9

Math.random() * (max - min + 1) // = 0 ~ 8.9999
Math.floor([prevValue])         // = 0 ~ 8
[prevValue] + min               // = 2 ~ 10
ding-co님의 프로필 이미지
ding-co
질문자

아.. 죄송합니다! 소괄호를 헷갈렸네요

 

-> const num = Math.floor(Math.random() * (max - min + 1) + min)

 

이렇게 입니다..!

정재남님의 프로필 이미지
정재남
지식공유자

제가 착각했습니다. 잘 되는것 같네요! ㅎㅎ

ding-co님의 프로필 이미지
ding-co

작성한 질문수

질문하기