솔적솔적

새로 고침 기능 구현 시, window.location.reload() 쓴다고?! 잠깐🙌 본문

Front-end

새로 고침 기능 구현 시, window.location.reload() 쓴다고?! 잠깐🙌

카드값줘체리 2024. 10. 23. 15:37

오늘의 글은

window.location.reload()가 위험할 수 있는 이유와,

React 프로젝트에서의 더 좋은 새로고침 전략에 대해서 정리해보고자한다.

 

 

버튼 클릭 시 “새로고침”이 필요하다는 요구사항을 종종 만납니다. 흔히 떠올리는 건 바로

window.location.reload();

하지만, 구현하면서 항상 생각해야한다.

이 코드가 우리 프로젝트에 적합한 코드인가?

 

 

왜 섣부른 전체 리로드가 위험할까

 

 

🤔상태 손실이 되어도 괜찮은가: 메모리 기반 상태(React state, Zustand 등 사용 시) 전부 초기화된다.

현재 참여 중인 프로젝트는 i18n을 적용해 한국어/일본어 다국어 선택 기능을 제공하고 있는데,

단순히 window.location.reload()를 사용하면 이 상태들도 모두 초기화될 수 있다.

새로고침 버튼의 목적은 "날짜 설정을 오늘 날짜로 되돌리고, 그에 따라 통계 데이터와 리스트를 다시 초기화"하는 것이었는데,

겉으로 보면 전체 리로드로 처리하는 게 간단해 보일 수 있습니다. 하지만 그렇게 접근하는 것 자체가 잘못된 선택일 수 있다.

예를 들어, 사용자가 일본어를 선택해 사용 중인데 초기 언어가 한국어로 설정되어 있다면, 전체 리로드 시 한국어로 되돌아가 버리게 된다. 물론 localStorage, cookie, IndexedDB 같은 영속 저장소에 저장해 둔 값은 리로드 후에도 유지되지만, 메모리 기반 상태만 의존하고 있다면 언어 설정이 초기화되는 문제가 생긴다.

따라서 언어 설정과 같은 값은 반드시 localStorage나 cookie 등 영속 저장소에 보관하고, 초기화 시점에 이를 읽어 i18n 설정에 반영하는 것이 올바른 접근이라고 생각한다. 

 

 

 

🤔 단순히 한번 띡, 갱신되는 것이 아닌, 전체 페이지와 모든 리소스를 서버에 다시 불러오는 것

다시 서버에 불러온다는건 뭐다? 👉 불필요한 네트워크 요청이 증가되는 것이다. 이는 과부화로 성능 저하/UX 저하가 되는 것이다.

특히 SPA(Single Page Application)구조라면 이런 문제가 더 두드러지는데,

예를 들어, React 프로젝트에서 메인 페이지 안에 여러 컴포넌트로 Header, Footer, 통계용 컴포넌트, 사용자 정보 컴포넌트, 리스트 컴포넌트등이 모두 모여 있다고 볼 때, 리로드를 해버리면 이 모든 컴포넌트들이 다시 한 번 전부 서버 요청을 발생시키고, 초기 렌더링부터 다시 시작하게 된다.

 

 

 

🤔 토큰 만료 상태유무 시 보안과 세션 이슈면에서도 괜찮은가

로그인 후 인증 토큰이 만료 상태라면, 예상치 못한 로그인 화면 리다이렉트가 발생할 수 있다.

새로고침 버튼 하나 때문에 사용자 흐름을 끊어버릴 수도 있으니 이 점 또한 주의해야한다.

 

 

🤔 화면 깜빡, SPA를 사용하는 장점 상실 -> UX 저하

window.location.reload()를 직접 적용해 보면 알 수 있듯,

화면이 순간적으로 깜빡거리고, 사용자가 내려서 보고 있던 스크롤 위치나 포커스도 초기화된다.

이로 인해 유저는 불편함을 느끼고, 애플리케이션은 SPA가 가진 매끄러운 화면 전환 장점을 잃어버린 채

전통적인 전체 리로드 방식의 성능 저하를 감수하게되는데, 이 부분도 괜찮은지 구현 전 확인해봐야한다.

 

 

 

그럼, window.location.reload()말고 어떻게 구현해야할까.

새로고침 기능을 꼭 구현해야 한다면 전체 페이지 리로드 대신 두 가지 방법을 고려할 수 있다.

- 상태 갱신 로직을 직접 구현하는 방법,

- 데이터만 다시 fetch해서 화면을 갱산하는 방법이 있다.

 

 

 

리액트 환경에서의 대안

현재 리액트를 사용하니, 리액트 기준으로만 말하자면,

 

- Zustand를 사용한다면:
특정 store의 state만 reset시키는 함수를 만들어 필요한 상태만 초기화
→ 전체 상태를 날리지 않고, 원하는 부분만 초기화 가능

 

- React Query를 사용한다면:
queryClient.invalidateQueries()를 활용해 특정 쿼리 데이터를 무효화하고 자동으로 다시 가져오도록 할 수 있다.

import { useQueryClient } from "@tanstack/react-query";

function RefreshButton() {
  const queryClient = useQueryClient();

  const handleRefresh = () => {
    // 특정 쿼리 키의 데이터만 다시 가져오기끔
    queryClient.invalidateQueries({ queryKey: ["driverList"] });
  };

  return <button onClick={handleRefresh}>새로고침 테스트</button>;
}

 

invalidateQueries : 기존 데이터를 무효화하고, React Query가 알아서 다시 fetch하게끔한다.

전체 데이터를 새로 불러오게하고 싶다면 queryclient.invalidateQueres()를 키 없이 호출할 수 있다. 

하지만 이렇게 사용 시 모든 쿼리가 한꺼번에 다시 요청되기에

과도한, 불필요한 refetch가 발생할 수 있으므로 쿼리 키를 지정하여 불러오는 것이 좋다. 

 

 

 

📃 요약하자면,
window.location.reload() 대신 Zustand reset이나 React Query invalidateQueries를 활용하면,
필요한 상태나 데이터만 선택적으로 초기화할 수 있고, 불필요한 네트워크 낭비와 UX 저하를 피할 수 있다.

 

 

📃 window.location.reload() 사용 시 주의점 정리

# 상태 손실: React state, Zustand/Redux 등 메모리 기반 상태가 전부 초기화된다.

# 전체 리소스 서버에 재요청은 불필요한 네트워크 증가로.

# SPA의 장점 상실

# 인증/세션 이슈 - 토큰 만료 시 예상치 못한 로그인 화면 이동이 발생 가능.

 

 

 

window.location.reload()는 무조건 전체 리로드라서 부분 갱신이 불가능하기에 간단한 한 줄처럼 보여도 의외로 무서운 함수다.

 

따라서, 새로고침 요구가 있어도 이 프로젝트에 정말 적절한가를 먼저 고민하는 것이 중요하다고 생각한다.

오늘도 이를 상기하며 글을 남긴다. 도움이 되셨길 바랍니다!