You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React-Admin:如何在authProvider中派发store action?

How to Dispatch Redux Actions in React-Admin's authProvider

Great question! Since React-Admin's authProvider isn't a React component, you can't use connect or React-Redux hooks like useDispatch directly—but there are straightforward ways to access the Redux store's dispatch method to fire your custom actions, even during the AUTH_LOGIN flow. Let's walk through the two most common approaches:

1. Pass dispatch to your authProvider during initialization

This is the cleanest approach, especially if you want to keep your authProvider decoupled from the store singleton.

First, set up your Redux store with your custom reducer:

// store.js
import { createStore, combineReducers } from 'redux';
import { adminReducer } from 'react-admin';
import accountReducer from './accountReducer'; // Your custom reducer

const rootReducer = combineReducers({
  admin: adminReducer,
  account: accountReducer, // Add your reducer to the root
});

export const store = createStore(rootReducer);

Next, create an authProvider that accepts dispatch as a parameter, then use it in your login flow:

// authProvider.js
export const createAuthProvider = (dispatch) => ({
  login: async ({ username, password }) => {
    // Step 1: Call your login endpoint
    const loginRes = await fetch('/api/login', {
      method: 'POST',
      body: JSON.stringify({ username, password }),
      headers: { 'Content-Type': 'application/json' },
    });

    if (!loginRes.ok) throw new Error('Login failed');
    const { token } = await loginRes.json();
    localStorage.setItem('authToken', token);

    // Step 2: Fetch account data from your separate endpoint
    const accountRes = await fetch('/api/account', {
      headers: {
        'Authorization': `Bearer ${token}`,
        'Content-Type': 'application/json',
      },
    });

    if (!accountRes.ok) throw new Error('Failed to fetch account data');
    const accountData = await accountRes.json();

    // Step 3: Dispatch your custom action
    dispatch({
      type: 'ACCOUNT_SET_DATA', // Your action type
      payload: accountData,
    });

    return Promise.resolve();
  },

  // Handle logout by clearing account data too
  logout: () => {
    localStorage.removeItem('authToken');
    dispatch({ type: 'ACCOUNT_CLEAR_DATA' });
    return Promise.resolve();
  },

  // Implement other required authProvider methods
  checkAuth: () => 
    localStorage.getItem('authToken') ? Promise.resolve() : Promise.reject(),
  checkError: () => Promise.resolve(),
  getPermissions: () => Promise.resolve(),
});

Finally, pass the store's dispatch to your authProvider when initializing the Admin component:

// App.js
import { Admin, Resource } from 'react-admin';
import { store } from './store';
import { createAuthProvider } from './authProvider';
// Import your resources here

const App = () => (
  <Admin
    store={store}
    authProvider={createAuthProvider(store.dispatch)}
  >
    {/* Add your resources */}
  </Admin>
);

export default App;

2. Import the store singleton directly

If you don't mind a tighter coupling between your authProvider and store, you can import the store directly and call store.dispatch():

// authProvider.js
import { store } from './store';

export const authProvider = {
  login: async ({ username, password }) => {
    // ... same login and account fetch logic as above ...

    // Dispatch action directly from the store
    store.dispatch({
      type: 'ACCOUNT_SET_DATA',
      payload: accountData,
    });

    return Promise.resolve();
  },

  // ... other authProvider methods ...
};

This works because your store is a singleton, so you can access it anywhere in your codebase. Just note this approach might cause issues with server-side rendering (if you're using it), but it's perfectly fine for client-only apps.

Key Notes

  • Make sure your custom reducer is properly combined into the root reducer—otherwise, your dispatched actions won't update the state.
  • Always handle errors in your async flows: if fetching account data fails, you might want to clear the auth token and throw an error to notify the user.
  • If you're using TypeScript, define action types and payload interfaces to keep your code type-safe.

内容的提问来源于stack exchange,提问作者user2078023

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 07:12:14