[야매] redux callback(?) 설정하기

유제·2021년 3월 11일

나의 상황

내가 보려는 아이템 (currentItem)을 store에 저장을 하고 Detail Screen으로 넘어간 후 currentItem을 불러오는 상황이다.

navigation.navigate에서 params로 데이터를 넘겨도 되는데 왜 이딴식으로 했는가?

사실 Detail Screen에서 외부 api의 response를 currentItem의 상태로 설정해야하는 앱이기 때문에 navigate의 params로 데이터를 넘기면 더 복잡해질 것 같았다. 그래서 위와 같은 구조로 만들었다. 그래야 api 호출이나 redux action 등이 더 간단해질 것 같다고 판단했다.

여기서 내가 겪은 문제는 1 -> 2로 넘어가는 과정에서 발생했다.Cannot update a component from inside the function body of a different component에러가 발생했다. 구글링을 하는데 내 상황에 맞는 답은 안나왔다. 그래서 그냥 혼자서 생각해보다가 왠지 1의 과정이 끝나지 않은 상태에서 2로 넘어가니까 에러가 발생하는 것 같았다. 그럼 1의 과정이 끝난 후에 2를 실행하면 되지 않을까? 생각해서 삽질을 했다. 마침 redux middleware인 redux-saga를 사용하고 있었기 때문에 여기서 쇼부를 보면 되겠다고 생각했다.

거두절미하고 코드부터 보면

function* setItemSaga({
  payload: { item, navigation },
}: ReturnType<typeof setItemAsync.request>) {
  yield put(setItemAsync.success(item));
  yield navigation.navigate('Detail');
}

이런식으로 했다. 비동기 작업이 아닌데도 async라는 이름을 붙인 이유는 다른 redux action들과 네이밍을 통일하기 위해서이다. 이렇게 하면 state가 업데이트 된 것이 보장되고 나서 navigate가 실행될 것 같았고, 역시나 맞았다. 물론 yield navigation.navigate('Detail'); 이 코드를 얻기까지 삽질을 했다.

사실 redux-saga를 이용해서 접근해야겠다고 생각은 했지만 어떻게 접근해야될지는 감이 잡히지 않았다. 그러던 중 react-navigation의 이슈를 보게되었다. 그리고 NavigationActions라는 것을 찾아보았더니 react-navigation이 v5으로 되면서 CommonActions로 이름이 바뀐 것 같았다. 그래서 맨 처음에는 아래처럼 접근했다.

yield put(CommonActions.navigate({name: "Detail"}));

그런데 이건 작동하지 않았다. 왜냐하면 put은 redux action을 dispatch해주는 것이기 때문이다. CommonActions은 redux랑 아무 관련이 없기 때문에 작동하지 않는다. 이걸 생각하지 못해서 여기서만 1~2시간 날렸고, 삽질한 코드의 종류는 아래와 같다.

yield put(navigation.dispatch(CommonActions.navigate({name: "Detail"})));
yield call(navigation.navigate, "Detail");
yield call(CommonActions.navigate, {name: "Detail"});

이렇게 삽질하다가 그냥 navigation.navigate("Detail")을 해볼까해서 해봤더니 됐다. 오늘은 기분좋게 잘 수 있을 것 같다. 그래도 payload에 navigation이 들어가는 게 마음에 들진 않는다. 이 문제를 현명하게 해결하신 고수분이 좋은 링크 남겨주시면 감사하겠습니다.

0개의 댓글