Blank page after logout when the app re-renders `<Admin>` during `authProvider.logout()`

オープン 初心者向け
#11,431 コメント 1 件 リアクション 0 件 担当者 0 名 GitHub で見る

メンテナーはふだん 1 日以内に返信

@uchiha-suraj がすでに取り組んでいます。

2026年10月30日 から。

評価

難易度
2/5
見積もり時間
1〜3時間
初心者へのやさしさ
76/100
issue の種類
バグ
明瞭さ
明確に書かれている
活発さ
活発
技術スタック
react, typescript
領域
frontend

調査の方向性

createHashRouter がレンダリング中に呼び出される packages/ra-core/src/routing/adapters/reactRouterProvider.tsx の InternalRouter から始めてください。useLogout が /login に遷移し、コンポーネントが再レンダリングされるとき、ルーターインスタンスがどのように使われるかを追ってください。説明した再現手順の後にログインページが表示されれば完了です。ログアウト中に <Admin> の上位にあるコンポーネントが再レンダリングされる場合も含みます。

索引モデルが issue の本文から書いたものです。

説明

What you were expecting:
When checkAuth fails, the user lands on the login page.

What happened instead:
The URL changes to #/login, but the page stays blank.
The router is still on the previous location, rendering LogoutOnMount (which renders null).

It happens whenever the component rendering <Admin> re-renders while authProvider.logout() is running.
Auth SDKs commonly trigger this: clearing the session notifies a context provider above <Admin>.

Steps to reproduce:

  1. Render the app below.
  2. Open /#/posts.
  3. The URL becomes /#/login, but nothing is rendered.

Related code:

import { useState } from "react";
import { Admin, CustomRoutes } from "react-admin";
import { Route } from "react-router-dom";

let rerender = () => {};

const authProvider = {
  login: () => Promise.resolve(),
  checkAuth: () => Promise.reject(new Error("no session")),
  checkError: () => Promise.resolve(),
  getPermissions: () => Promise.resolve(),
  logout: () => {
    rerender(); // stands for an auth SDK notifying the app that the session was cleared
    return Promise.resolve();
  },
};

export const App = () => {
  const [, setTick] = useState(0);
  rerender = () => setTick((t) => t + 1);
  return (
    <Admin authProvider={authProvider} requireAuth loginPage={() => <div>Login page</div>}>
      <CustomRoutes>
        <Route path="/posts" element={<div>Posts</div>} />
      </CustomRoutes>
    </Admin>
  );
};

Other information:

  • Cause: InternalRouter in packages/ra-core/src/routing/adapters/reactRouterProvider.tsx calls createHashRouter(...) in its render body.
    Every re-render creates a new router at the current URL.
    The navigate("/login") scheduled by useLogout goes to the discarded router: it updates the URL, but the current router never sees it.

  • Suggested fix: create the router once, e.g. with useState(() => createHashRouter(...)).

  • Workaround: wrap the app in a router created once, which RouterWrapper then uses:

    const router = createHashRouter([{ path: "*", element: <App /> }]);
    root.render(<RouterProvider router={router} />);
    

Environment

  • React-admin version: 5.15.5
  • React version: 19.3.1
  • React Router version: 7.18.4
主要言語
TypeScript
スター
27k
フォーク
5.5k
平均マージ
1日 3分
マージ済み PR(30日)
32

環境構築

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

marmelab/react-admin のほかの issue

marmelab/react-admin の issue をすべて見る

似ている issue

TypeScript の issue をもっと見る

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。