개발 내용

이제부터 서버에서 테이블 개수를 저장하게 되면서 테이블 개수 저장 처리를 debounce를 적용해서 진행하게 되었다.


배운 내용

기존 코드는 localstorage를 사용하고 있었어서 크게 어렵지 않게 구현할 수 있었다.

function AdminOrderManage() {
  const [tableCount, setTableCount] = React.useState(1);

  const handleTableCount = (count: number) => {
    setTableCount(count);
    localStorage.setItem(`workspace-${workspaceId}-tableCount`, count.toString());
  };
  ...
}

handleTableCount는 추가, 삭제 버튼이 눌릴 때마다 count 값을 1씩 조정해서 콜이 된다. localstorage를 사용할 때는 이 부분에 대한 부하는 거의 없는 편이므로 편하게 위와 같은 방식으로 구현해서 사용하고 있었다.

다만 이제는 tableCount를 서버에 저장해줘야 하는 상황이다. 위와 같은 방식으로 테이블 개수를 저장하는 request를 날리게 된다면 서버 부하도 부하지만 빠른 테이블 추가와 삭제가 안되는 것처럼 보이는, 즉 ux가 떨어지는 기능처럼 보일 수 있게 된다.

우리 서버 api 상으로 table 개수를 넘겨서 저장하기 때문에 중간에 많은 호출을 할 필요가 없다고 판단했다. 그래서 debounce 함수를 적용해야겠다고 생각했다.

debounce란 일정 시간동안 발생한 이벤트를 그룹화하여, 맨 처음이나 맨 마지막 이벤트만 발생시켜 부하를 막는 기술

먼저 적용하려고 했을 때는 아래와 같이 시도했었다.

function AdminOrderManage() {
  const { workspaceId } = useParams<{ workspaceId: string }>();
  const { fetchWorkspace, updateWorkspaceTableCount } = useAdminWorkspace();
  const workspace = useRecoilValue(adminWorkspaceAtom);

  const [tableCount, setTableCount] = React.useState(1);

  useEffect(() => {
	  const delayDebouncedId = setTimeout(() => {
      updateWorkspaceTableCount(workspaceId, tableCount);
    }, 300);
  
    return () => clearTimeout(debouncedId);
  }, [tableCount]);

  const handleTableCount = (count: number) => {
		setTableCount(count);
  };
  
  useEffect(() => {
    // will be deleted
    localStorage.removeItem(`workspace-${workspaceId}-tableCount`);
    fetchWorkspace(workspaceId);
  }, []);
  ...
}

이렇게 구현하니 생긴 문제점은 useEffect내부에 fetchWorkspace 실행되기전 tableCount 가 1로 초기화되고, 이 때문에 updateWorkspaceTableCount가 실행된다. 즉 이 구문이 table 개수를 항상 1로 초기화 시키게 되어버렸다.

그래서 맨처음 tableCount의 초기값을 workspace.tableCount 로 받게끔 진행해봤는데, 아직 workspace가 fetch되기 전이라서 recoil의 기본값이 들어있게 된다. 그러면 다시 위에 기술한 상황이 똑같이 발생한다.