:ledger: next.js에서 Server Action을 React Query에 사용하다.

next.js를 사용한 스파르타 최종 프로젝트에서 경험한 내용입니다.

:one: 개요

next.js의 클라이언트 컴포넌트에서 react query를 사용하여 서버액션 함수를 호출해서 queryFn에 넣어주었다. 이렇게 적용했을 때 데이터 패칭은 이루어진다. 사실 이 부분에 대해서 어색함을 못 느끼고 작업하고 있던 중 다른 이슈사항이 있어, 튜터님께 도움을 요청했고 튜터님이 문제를 확인해주며 클라이언트 컴포넌트에서 서버액션을 사용한 이유에 대해 물어보셨고 나는 대답을 할 수 없었다.

:two: 그렇다면 사용해도 되는걸가?

먼저 서버-클라이언트 실행 환경의 차이를 이해해야한다.

  • 서버 액션 함수는 서버 환경에서 실행되고 클라이언트 환경에서는 fetch나 API 호출을 통해 서버와 통신을 해야한다.
  • 클라이언트 컴포넌트는 브라우저에서 실행되기 때문에, 서버 전용 함수(예: 데이터베이스 작업이나 비공개 서버 로직)를 직접 실행할 수 없다. 브라우저는 파일 시스템, 서버리소스 등의 접근 권한이 없기 때문

:pushpin: 2-1) 근데 왜 데이터 패칭은 성공함?

그런데 왜 react query에 서버액션 함수를 queryFn에 넣어줬을 때 데이터 패칭은 성공하는가? 이 부분에서 이해가 되지 않되었는데, 이유는 아래와 같았다.

  • React QueryqueryFn에 서버 액션 함수를 넣을 때 클라이언트에서 HTTP 요청을 통해 서버 액션을 호출하고, React Query가 그요청의 응답을 처리하기 때문에 동작하는 것임
  • 하지만 서버와 클라이언트의 경계를 무너뜨릴 수 있으며, 코드가 실행할 때 예상하지 못한 문제가 생길 수 있음

:pushpin: 2-2) 분석

  • 서버 액션의 본질
    • 서버액션은 보통 서버 측에서 실행되고 보안이 필요한 로직을 처리하는데 적합
    • Next.js와 같은 프레임워크에서 서버 액션은 서버 환경에서만 실행되며, 클라이언트가 호출할 때도 서버에서 동작함.
  • React Query 사용 목적
    • 클라이언트 측에서 데이터를 가져오고 캐시하여 상태를 관리하는데 중점을 둠
    • 클라이언트가 API 엔드포인트를 호출하거나 데이터베이스와 통신을 처리하는 코드에 주로 사용
  • 서버 액션을 React Query의 queryFn에 사용하는 경우 문제점
    • 서버-서버 호출: queryFn에 서버 액션을 사용하면 클라이언트 컴포넌트에서 React Query가 서버 액션을 호출하여 다시 서버에 요청을 보낸다. 이는 클라이언트에서 데이터를 가져오기 위해 불필요한 서버 간의 왕복이 발생할 수 있음
    • 복잡성 증가: 서버 액션은 서버에서 실행되니까 리액트 쿼리에서 사용하는 것은 복잡한 데이터 흐름일 수 있음

:pushpin: 2-3) 결론

동작은 하지만, 중요한 것은 동작을 하는 것이 아니었다. 서버액션을 왜 사용하는가?라는 부분에서 이해를 하지 않고 접근했던 것이 문제였다. 서버액션 함수를 사용하는 이유는 민감한 데이터나 서버 전용 로직이 포함될 때 사용하는데, 호출하는 곳이 클라이언트이고 성공 여부를 떠나 사용하려는 이유에서 의문을 가지게 되는것 결론은 서버액션함수를 queryFn으로 데이터 패칭이 성공할 수 있지만 이 방식은 서버액션을 사용하는 이유인 보안과 코드 사용성 측면에서 옳지 않다.

:fire: 마무리

서버 액션 함수를 queryFn으로 사용해 데이터 패칭이 성공할 수 있지만, 이 방식은 보안과 코드 사용성 측면에서 적절하지 않다.

  • 서버 컴포넌트에서 props를 통해 패칭된 데이터를 클라이언트 컴포넌트로 전달
  • 서버액션이 아닌 route handler 사용하여 클라이언트 컴포넌트에서 데이터 패칭

즉, 서버 컴포넌트에서는 서버 액션을 사용하여 서버에서 안전하게 데이터를 처리하고, 클라이언트 컴포넌트에서는 React Query와 라우트 핸들러를 사용해 클라이언트에서 효율적으로 데이터 패칭과 상태 관리를 수행하는 것이 좋은 방법이 아닐까란 생각을 한다.