DevToolsManager
class DevToolsManager implements Manager
与 Redux DevTools 集成,用于跟踪状态和 action。注意:不支持时间旅行(time-travel)。
在浏览器中安装 Chrome 扩展或 Firefox 扩展即可开始使用。
implements
DevToolsManager 实现了 Manager
constructor(options?, skipLogging?)
options
传给 redux devtools 的参数。
例如,我们可以启用 trace 选项,帮助追踪 action 是从哪里 dispatch 的。
- Web
- React Native
- NextJS
- Expo
index.tsx
import { DataProvider, getDefaultManagers } from '@data-client/react';
import { createRoot } from 'react-dom/client';
import App from './App';
const managers = getDefaultManagers({
devToolsManager: { trace: true },
});
createRoot(document.body).render(
<DataProvider managers={managers}>
<App />
</DataProvider>,
);
index.tsx
import { DataProvider, getDefaultManagers } from '@data-client/react';
import { AppRegistry } from 'react-native';
import App from './App';
const managers = getDefaultManagers({
devToolsManager: { trace: true },
});
const Root = () => (
<DataProvider managers={managers}>
<App />
</DataProvider>
);
AppRegistry.registerComponent('MyApp', () => Root);
app/Provider.tsx
'use client';
import { getDefaultManagers } from '@data-client/react';
import { DataProvider } from '@data-client/react/nextjs';
const managers = getDefaultManagers({
devToolsManager: { trace: true },
});
export default function Provider({
children,
}: {
children: React.ReactNode;
}) {
return <DataProvider managers={managers}>{children}</DataProvider>;
}
app/layout.tsx
import Provider from './Provider';
export default function RootLayout({ children }) {
return (
<html>
<body>
<Provider>{children}</Provider>
</body>
</html>
);
}
app/_layout.tsx
import { Stack } from 'expo-router';
import { DataProvider, getDefaultManagers } from '@data-client/react';
const managers = getDefaultManagers({
devToolsManager: { trace: true },
});
export default function RootLayout() {
return (
<DataProvider managers={managers}>
<Stack>
<Stack.Screen name="index" />
</Stack>
</DataProvider>
);
}
skipLogging
(action: ActionTypes) => boolean
可以跳过某些 action,使其不记录到浏览器 devtool 中。
默认会跳过进行中的 fetch action
- Web
- React Native
- NextJS
- Expo
index.tsx
import {
DataProvider,
DevToolsManager,
getDefaultManagers,
} from '@data-client/react';
import { createRoot } from 'react-dom/client';
import App from './App';
// production builds leave out DevToolsManager
const managers = getDefaultManagers({
devToolsManager: new DevToolsManager(undefined, () => true),
});
createRoot(document.body).render(
<DataProvider managers={managers}>
<App />
</DataProvider>,
);
index.tsx
import {
DataProvider,
DevToolsManager,
getDefaultManagers,
} from '@data-client/react';
import { AppRegistry } from 'react-native';
import App from './App';
// production builds leave out DevToolsManager
const managers = getDefaultManagers({
devToolsManager: new DevToolsManager(undefined, () => true),
});
const Root = () => (
<DataProvider managers={managers}>
<App />
</DataProvider>
);
AppRegistry.registerComponent('MyApp', () => Root);
app/Provider.tsx
'use client';
import { DevToolsManager, getDefaultManagers } from '@data-client/react';
import { DataProvider } from '@data-client/react/nextjs';
// production builds leave out DevToolsManager
const managers = getDefaultManagers({
devToolsManager: new DevToolsManager(undefined, () => true),
});
export default function Provider({
children,
}: {
children: React.ReactNode;
}) {
return <DataProvider managers={managers}>{children}</DataProvider>;
}
app/layout.tsx
import Provider from './Provider';
export default function RootLayout({ children }) {
return (
<html>
<body>
<Provider>{children}</Provider>
</body>
</html>
);
}
app/_layout.tsx
import { Stack } from 'expo-router';
import {
DataProvider,
DevToolsManager,
getDefaultManagers,
} from '@data-client/react';
// production builds leave out DevToolsManager
const managers = getDefaultManagers({
devToolsManager: new DevToolsManager(undefined, () => true),
});
export default function RootLayout() {
return (
<DataProvider managers={managers}>
<Stack>
<Stack.Screen name="index" />
</Stack>
</DataProvider>
);
}
跳过高频更新
使用 WebSocket 或其他实时数据源时,高频更新可能会让 DevTools 扩展不堪重负。使用 predicate 选项过滤掉特定的 action 类型或 schema:
managers.ts
import { getDefaultManagers, actionTypes } from '@data-client/react';
import { Ticker } from './resources/Ticker';
const managers = getDefaultManagers({
devToolsManager: {
// Increase latency buffer for high-frequency updates
latency: 1000,
// Skip WebSocket SET actions for Ticker to reduce log spam
// (including batched set([Ticker], rows) writes)
predicate: (state, action) =>
action.type !== actionTypes.SET ||
(action.schema !== Ticker && action.schema[0] !== Ticker),
},
});
以编程方式访问 store
在开发模式下,DevToolsManager 会把每个 Controller 注册到
globalThis.__DC_CONTROLLERS__ 上——这是一个以 devtools 连接名为键的 Map。它适用于浏览器、React Native 和 Node。
Browser DevTools console
// List all registered providers
__DC_CONTROLLERS__.keys();
// Get state from the first provider
__DC_CONTROLLERS__.values().next().value.getState();
// Get state by name
__DC_CONTROLLERS__.get('Data Client: My App').getState();
这对使用 Chrome DevTools MCP 或 Expo MCP 的 AI 编程助手很有用,它们可以借此以编程方式检查 store 并与之交互。每个 DataProvider 都会独立注册,因此完全支持同一页面上存在多个 provider。
调用 cleanup() 时,Controller 会从该 map 中移除。
更多信息
使用这个 Manager 可以在浏览器中进行调试和 store 检查。