[React Native] react-native-zoomable-view binderToBorder prop 사용시 문제점

STEVELOPER·2023년 3월 28일
0

React Native

목록 보기
2/2

React 에서 확대/축소 기능을 사용할 일이 생겼다.
React 에서 이런 사용자의 터치 동작을 추적하고 그에 따른 이벤트를 발생시킬 수 있는 기능은 react-native 패키지의 PanResponder 라는 기능을 사용한다.
확대/축소 기능 또한 PanResponder 에서 제공하는 기능들, 예를 들어,
터치가 몇개인지, 터치한 부분에서 얼마정도 움직였는 지 등을 추적할 수 있기 때문에 확대/축소 또한 처음부터 만들 수 있겠지만 보통 간단한 일이 아니었다.
직접 만들어보자 생각한 것도 이미 만들어져 있는 react-native-zoomable-view 라는 패키지를 사용하다 특정 문제가 발생해서 직접 만들어보려 했지만 그러기엔 신경 쓸 부분도 너무나 많았고 차라리 계속해서 프로젝트를 진행하려면 이것만 붙잡고 있을 수 없다고 판단해 react-native-zoomable-view 에서 발생한 이 특정 문제를 해결하려 했고 문제점을 파악할 수 있었다.

react-native-zoomable-view 를 사용하면서 내게 발생한 문제는
bindToBorder 기능을 사용하는데 도중에 풀려버리는 문제였다.
참고로 해당 패키지는 @dudigital 이 개발했으나 이후 개발/유지보수는
@openspacelabs 에 의해 관리되게 되었으므로 처음 사용하는 사람은 이 점을 유의해서 npm install 을 해야한다.

bindToBorder 문제로 돌아가서, 발생 원인은 특정 행동을 하면 이 기능이 풀려버리는 듯한 문제가 발생하는 것이었는데,
문제점을 더 자세히 얘기하자면, 해당 component 에 접근해서 처음으로 rendering 이 되면서 zoomable view 가 생성됐을 때는 정상적으로 동작하다가 특정 행동인 드래그를 하고 다른 component 로 이동했다가 다시 해당 component 로 돌아올 시 bindToBorder 가 풀리는 현상이 발생했다.
원인은 rerender 였다.
react-native-zoomable-view 를 사용해 만든 component 와 같은 depth 에서 setState 를 통해 rerender 가 발생할 경우 이 bindToBorder 기능이 풀리고 드래그로 zoomable view 가 화면 밖으로 나갈 시 자동으로 돌아와야 할 것이 슝 날아가버리는 것이었다.
나의 경우 전역 state 를 사용하기위해 @apollo/client 의 useReactiveVar 를 사용하는 중이었고 해당 문제가 발생하는 component 에서 해당 전역 state 를 참조하고 있었으므로 setState 가 발생할경우 rerender 가 발생하면서 bindToBorder 를 풀어버린 것이었다.
이 문제를 파악하는 과정에서 해당 문제가 확실한지 파악하기 위해 로컬 state 를 만들어 테스트를 해보았더니 같은 문제가 발생했다.

const [test, setTest] = useState();

상기와 같이 state 를 정의해두고 특정 행동을 하여 rerender 가 발생하도록 한 뒤, 다른 위치로 이동 후 다시 돌아왔을 때 같은 현상이 발생함을 확인하고 나서야 문제는 rerender 라는 것을 알 수 있었다.

상기에서도 언급한 실제 문제인 전역변수를 참조하는 코드는 다음과 같다.

const problemVar = useReactiveVar(PROBLEM_VAR)

PROBLEM_VAR 는 @apollo/client 에서 같이 제공하는 함수인 makeVar 를 통해 생성한 변수이다. 이를 상기와 같이 사용하면 problemVar 는 해당 변수를 참조하고 있게 되고 값이 변경될 시 useState 와 같이 해당 component 를 rerender 한다.

해당 참조 변수를 제거하고 테스트를 해본 결과, 같은 문제가 발생하지 않았고,
하위 component 로 해당 참조 변수를 생성해서 같은 기능이 동작하도록 구현했을 때 또한 문제가 발생하지 않았다.
전역 state 를 set 하는 동작 자체는 문제가 되지 않았으나 해당 state 를 "참조" 하고 있어 "rerender" 를 발생시키는 것이 문제였다.

profile
JavaScript, Node.js, Express, React, React Native, GraphQL, Apollo, Prisma, MySQL

0개의 댓글