리덕스 사가 작업 취소

Felix Yi·2020년 4월 12일
0

컴포넌트가 라우터 주소 바뀌면 비동기 요청.
그리고 비동기 요청결과에 의존하는 다른 컴포넌트 존재.

그럼 /a 에서 요청하고 /b 로 재빨리 이동했을 때 나는 /b 의 결과만 보여주고 싶은데 꼭 /a 의 결과 다음에 /b 의 결과를 보여준다.

그럼 이전에 실행된 task 를 중단해야하고, cancel 이 있고.. race 가 있고...

https://stackoverflow.com/questions/37689562/cancel-a-saga-when-an-action-is-dispatched-with-redux-saga

위처럼 한 컴포넌트 내에서는 이전 것을 취소할 수 있다.

그럼 이제 새로운 케이스. 로케이션 변경 시 이전에 보던 컴포넌트에서 실행된 액션을 취소시키려면? 위치 변경 시마다 한방에?

A 컴포넌트에서 비동기 요청 후 B 컴포넌트로 이동 시 사가는 계속 돌아가서 Success 인지 Fail 인지 꼭 끝장을 본다.

아무 사이드 이펙트가 없으면 모르겠는데.. A 컴포넌트 성공시 특정 리듀서 상태 를 업데이트하고, 그 리듀서에 B 컴포넌트가 의존할 때, B 컴포넌트는 자기가 하지도 않았는데 엉뚱하게 변화된 상태때문에 몇 번이고 리렌더링이 된다.

아주그냥... ruoter.replace 때문에 그럴까? 아 너무 모르겠다. 나는 미쳐버리겠어.

https://formidable.com/blog/2017/real-world-redux-saga-patterns/

export default function* forkHandleCheckAuthFetch() {
  let task;

  while (true) {
    // this loop stops here until one of the actions is triggered
    const action = yield take([CheckLocalAuthActionType.REQUEST_SEND, LoginActionType.REQUEST_SEND]);

    // both the actions cancel the previous forked task (similar to what `takeLatest does`)
    // 어째됐던 이전에 실행되던 거 취소!
    if (task) {
      cancel(task);
    }

    // 구체적인 타입이 지정된 액션만 실행. 즉 로그인액션타입.REQUEST_SEND는 암것도 하는 거없이 작업 캔설만 시킴
    if (action.type === CheckLocalAuthActionType.REQUEST_SEND) {
       // 액션 객체를 변수에 담기. fork 는 cancel 이 가능함...
      task = yield fork(handleCheckAuthFetch, action);
    }
  }
}

위 코드. 그니까 로케이션 변경 때 LoginActionType.REQUEST_SEND 같이 뭔 이름이든 상관 없으니까 액션 만들고, 위처럼 무한루프(wile 이나 takeEvery) 도는 곳 안에서 무조건 캔슬을 시켜주기로 하면 됨.

  useEffect(() => {
    dispatch(액션A())
    return function cleanup() {
      dispatch(액션A취소());
    };
  }, [calendarIsLoading, recordDays]);

... 아 그럴 필요까지는 없네. useEffect 클린 콜백 쓰면 된다. 메모리 누수 경고가 나오던게 이것 때문인가 싶네. 아으.. 빡친다.

아 부질없다. 주말에 무슨 짓이냐. 이게. 아 리액트 사가, 너란 존재는.. 지금 이가 갈리는구나.

profile
다른 누구와도 같은 시장 육체 노동자

0개의 댓글