Auto Refresh with React-Admin Data Provider Hooks

LeeJaeChanLeeJaeChan
2 min read

🚨 이슈 내용

사내에서 사용 중인 React-Admin으로 개발된 프로젝트가 있는데, 이 프로젝트의 Datagrid에서 Edit Row 하는 기능에서 이슈가 발생하였습니다.

주요 내용은 Datagrid 내부에서 각 Row를 수정할 경우에, Datagrid의 data를 모두 잃고, 새로고침을 해야 데이터를 새로 받아와 수정된 데이터가 정상적으로 노출이 되는 이슈였습니다.

🧐 원인 분석

React-Admin은 Data Provider를 통해 백엔드 API와 소통할 수 있고, 이를 위해 여러 Hooks를 제공하고 있습니다.

해당 Datagrid 또한 useGetList라는 hooks을 이용해 Datagrid의 데이터를 가져오고 있었고, useUpdate을 통해 row edit을 진행하고 있었습니다.

원인을 트래킹하며 useUpdate에 onSuccess property를 걸어 값을 확인해보니 정상적으로 동작하고 있었습니다.

다만 이후에 화면이 재렌더링 되는 과정에서 useGetList가 다시 동작하지는 않고, useGetList을 통해 가져온 Data가 Empty Array가 되는 것을 확인하였습니다.

🛠️ 해결 방법

  1. onSuccess Property에 useRefresh hook을 걸어준다.

React-Admin을 사용해본 사람이라면 가장 먼저 떠올릴 수 있는 방법이 아닐까 싶습니다.
현재 이슈에서 새로고침을 하면 정상적으로 수정된 데이터를 새로 받아올 수 있으니, useRefresh를 통해 화면을 새로 그리면 보통은 해결될 것이라 생각했습니다.

updateMethod(resource, id, record, {
    onSuccess: () => {
        useRefresh();
    }
})

하지만 해결되지 않았다.. 아무 변화가 없었다.

  1. useUpdate hook 파고들기

React-Admin은 써본 사람은 알겠지만, 공식문서가 무척이나 부실합니다. 훨씬 많은 기능이 구현되어 있는데, 공식문서에서는 이를 전혀 알려주지 않는 경우가 많습니다.

그래서 프로젝트를 진행하며 자주 해온 일이지만, 이번에도 해당 module을 파헤쳐 보기로 했습니다.

useUpdate method

이게 useUpdate의 기본적인 구조입니다. 보시다 싶이 공식문서보다 훨씬 많은 내용이 담겨있는걸 볼 수 있습니다. onSuccess property는 options에 포함되어 있으므로 options를 확인해 보았습니다.

// useUpdate.options
options?: MutationOptions

// MutationOptions Type
export interface MutationOptions {
    action?: string;
    returnPromise?: boolean;
    onSuccess?: OnSuccess | DeclarativeSideEffect;
    onFailure?: OnFailure | DeclarativeSideEffect;
    withDeclarativeSideEffectsSupport?: boolean;
    /** @deprecated use mutationMode: undoable instead */
    undoable?: boolean;
    mutationMode?: MutationMode;
}

// OnSuccess Type
export type OnSuccess = (response?: any) => void;

// DeclarativeSideEffect type
export interface DeclarativeSideEffect {
    notification?: NotificationSideEffect;
    redirectTo?: RedirectionSideEffect;
    refresh?: boolean;
    unselectAll?: boolean;
}

위의 1번의 해결 방법의 경우는 onSuccess에서 OnSuccess 타입(void)에 useRefresh를 작성하는 방식이었습니다.

  1. DeclarativeSideEffect

결론적으로 아래와 같은 코드로 해결할 수 있었습니다.

updateMethod(resource, id, record, {
    onSuccess: {
        refresh: true;
    },
    withDeclarativeSideEffectsSupport: true;
})

withDeclarativeSideEffectsSupport property를 true로 놓지 않으면, DeclarativeSideEffect 타입은 제대로 동작하지 않고 이슈를 발생시키므로 주의하시기 바랍니다.

📝 결론

결과적으로 저는 2, 3번의 방법을 통해 해당 이슈를 해결할 수 있었습니다.

하지만 이는 저의 React-Admin 버전이 낮았기 때문에 이렇게 해결한 것이지, 현재 최신 버전에서는 1번의 방식으로 해결하면 될 것이라고 판단됩니다.

무엇보다 DeclarativeSideEffect는 최신의 React-Admin에서 deprecated 되었습니다.

1
Subscribe to my newsletter

Read articles from LeeJaeChan directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

LeeJaeChan
LeeJaeChan

🌈 Front-end Developer, 3yrs 🌈 3년차 프론트엔드 개발자입니다. 🇰🇷 Work in Seoul, Korea 🇰🇷 대한민국, 서울에서 일하고 있어요. 🔥 Striving for growth every day 🔥 매일매일 성장을 추구해요. 💻 Passionate about exploring diverse cutting-edge web technologies 💻 최신 웹 기술에 관심이 많아요 👉 Interested in connecting with people 👉 사람들과 교류하는데 흥미가 많아요. 🚀 Let's grow from yesterday! 🚀 어제보다 성장하기! 😀 Let's code with joy! 😀 즐겁게 코딩하기!