[React][DJplaylist] redux, useSelector와 deep copy

jiseong·2021년 10월 18일
0

T I Learned

목록 보기
103/291

현재 웹 어플리케이션에서는 음악을 재생할 수 있는 상황은 검색 컴포넌트에서 검색하여 나온 음악들 중 한 음악을 선택하는 상황 그리고 메인 컴포넌트에서 플레이리스트에 추가했던 음악들 중 한 음악을 선택하는 상황, 두 가지 상황이 존재한다.

하지만 추가적으로 위 상황들 속에서 음악이 재생되는 방식을 아래와 같은 조건을 지키면서 재생되게 하고 싶었다.

  1. 검색을 통해 나온 음악 중 동일한 음악을 여러번 재생을 눌러도 처음부터 재생되지 않기
  2. 플레이리스트의 음악 중 동일한 음악을 여러번 재생을 눌러도 처음부터 재생되지 않기
  3. 검색을 통해 나온 음악들 중 하나의 음악을 재생하였고 마음에 들어 플레이리스트에 추가하고 플레이리스트에서 해당 음악 재생을 했을 때 처음부터 재생되기

1번과 2번의 경우에는 추가적인 코드를 작성하지 않더라도 객체의 참조값이 동일하기 때문에 생각했던 방식대로 동작이 되었지만 3번의 경우에는 조금 달랐다.

그래서 다르게 인식시키기 위해 검색해서 선택한 음악인지 플레이리스트에서 선택한 음악인지 판별하는 변수를 추가해야할지 고민이 있었는데 결과를 말하자면, 변수를 추가하지 않고도 Deep Copy를 통해 해결할 수 있었다.

그 이유는 reducer 내부에서 저장하는 selectedMusic의 내부 값은 같을지라도 플레이리스트에 추가할 때 Deep Copy를 통해 독립적인 메모리에 할당 시킴으로써  검색해서 선택한 음악과 플레이리스트에서 선택한 음악의 참조값이 달라져 같은 음악이라 하더라도 처음부터 재생시킬 수 있게 되었다.

function* addDjplaylist({ payload: selectedMusic }) {
  const djPlaylist = yield select(state => state.music.djPlaylist);

  const isIncludeMusic =
    djPlaylist.filter(item => item.videoId === selectedMusic.videoId).length > 0;

  if (isIncludeMusic) {
    // 이미 존재하는 음악 처리
  } else {
    // 1 level deep copy
    const copiedSelectedMusic = { ...selectedMusic };

    yield call(setItem, 'djplaylist', [copiedSelectedMusic, ...djPlaylist]);
    yield put(addDjplaylistSuccess(copiedSelectedMusic));
  }
}

이 과정에서 object는 1 deep copy만 일어나는 새로운 사실도 알 수 있었고 불필요한 리렌더링을 방지하기 위해 useSelector 최적화에 대해서 좀 더 알아갈 수 있었다.

0개의 댓글