@bugsplat/react

中文文档
2.1.1发布于 2026/04/19MITTypeScriptCommonJS近 30 天下载 3016

用于反应的 bugsplay 工具

中文使用文档
文档目录15 节
  1. 为繁忙的开发者构建了崩溃和错误报告 .
  2. 导言
  3. 开始
  4. 进一步融合
  5. 用户反馈
  6. 高级使用
  7. 这个 scope 属性
  8. API 密码
  9. init()
  10. getBugSplat()
  11. ErrorBoundary
  12. withErrorBoundary
  13. useErrorHandler
  14. useFeedback
  15. 测试套件

bugsplat-github-banner-basic-outline

BugSpla

为繁忙的开发者构建了崩溃和错误报告 .

导言

BugSplat支持在React应用程序中收集出错和用户反馈. 这个 @ bugsplat/ react npm 软件包执行一个 边界错误 组件,以获取子组件的渲染错误 把它们送到BugSplat , 在那里可以跟踪和管理它们。 它还规定: (单位:千美元) useFeedback 用于收集用户反馈的钩子, 如标题, 描述, 文件附件。 在您的 React 应用程序中添加 BugSplate 是极其严重的 很简单。 在开始之前,请完成下列任务:

开始

要在您的 React 应用程序中开始使用 BugSplat, 请运行以下命令 在您的项目根部。 这将安装 @ bugsplat/ react 并且它是 次级依赖性, 错误板。 。 。 .

npm i @bugsplat/react --save

除标准外 package.json 属性 name 财务报告和审定财务报表 version,包括 (单位:千美元) database 属性 package.json 带有您 BugSplat 值的文件 数据库。 确保替换 {{YOUR_DATABASE_NAME}} 与你的实际 数据库名称.

// package.json
{
  "name": "my-app",
  "version": "1.2.0",
  "database": "{{YOUR_DATABASE_NAME}}"
  // ...
}

在您的项目根中,导入您的项目 package.json使用它来 name, (中文(简体) ), database,以及 version 要初始化 BugSplate 客户端的属性 因为发送崩溃。 这样可以即时处理一个新的客户端实例并存储它 内部.

// src/index.tsx

import { createRoot } from 'react-dom/client';
import { init } from '@bugsplat/react';
import App from './App';
import * as packageJson from '../package.json';

init({
  database: packageJson.database,
  name: packageJson.name,
  version: packageJson.version,
});

const root = createRoot(document.getElementById('root'));

root.render(<App />);

你现在可以用 ErrorBoundary 要抓取渲染 错误并自动与内部客户端一起发布到 BugSplat 我们刚开始的.

// src/App.tsx

import { ErrorBoundary } from '@bugsplat/react';

export default function App() {
  return (
    <ErrorBoundary fallback={<h1>Oops, there was a problem.</h1>}>
      <Content>...</Content>
    </ErrorBoundary>
  );
}

您也可以访问存储 BugSplat 地点 电话 getBugSplat()

// src/App.tsx

import { getBugSplat } from '@bugsplat/react';

export default function App() {
  const handleClick = () => {
    getBugSplat().post('There was a problem');
  };

  return (
    <div>
      <h1>Hello, world!</h1>
      <button onClick={handleClick}>Post Error Report</button>
    </div>
  );
}

进一步融合

想要您的错误边界同时处理未被捕获的错误 ErrorBoundary,例如同步错误或事件处理器? 没问题! useErrorHandler 去营救 将错误传递给返回的调用 useErrorHandler 将错误传播到最近的 ErrorBoundary。也可以将错误直接传递给 useErrorHandler 如果您管理错误, 或从另一个库获取.

// src/App.tsx

import { useState } from 'react'
import { ErrorBoundary, useErrorHandler } from '@bugsplat/react';

function NestedComponent() {
  const handleError = useErrorHandler();

  const handleClick = async () => {
    try {
      await doThing();
    } catch (err) {
      handleError(err);
    }
  };

  return <button onClick={handleClick}>Do Thing</button>;
}

function NestedComponent2() {
  const [error, setError] = useState<Error>()

  useErrorHandler(error)

  const handleClick = async () => {
    try {
      await doThing()
    } catch (err) {
      setError(err)
    }
  }

  return <button onClick={handleClick}>Do Thing</button>;
}

export default function App() {
  return (
    <ErrorBoundary fallback={<h1>Oops, there was a problem.</h1>}>
      <NestedComponent />
      <NestedComponent2 />
    </ErrorBoundary>
  );
}

提供 BugSplate 实例将允许 ErrorBoundary 自动 错误被它捕获到 BugSplat .

这个 ErrorBoundary 组件装有可用于 定制以适应您的需要:

  • fallback
  • onMount
  • onUnmount
  • onError
  • beforePost
  • onReset
  • onResetKeysChange
  • disablePost

我们强烈建议通过 fallback 将生成的道具 何时 ErrorBoundary 遇到错误.

这个 fallback 道具可以是任何有效的元素 :

function Component() {
  return (
    <ErrorBoundary fallback={<div>Oops, there was a problem.</div>}>
      ...
    </ErrorBoundary>
  );
}

...或使一个函数

function Component() {
  return (
    <ErrorBoundary
      fallback={(fallbackProps) => <div>Oops, there was a problem.</div>}
    >
      ...
    </ErrorBoundary>
  );
}

若为 fallback 是函数,将调用

  • error - 发现的错误是 ErrorBoundary
  • componentStack - 错误的组件堆栈跟踪
  • response - 向 BugSplat 发布错误的 BugSplate 响应(如果适用)
  • resetErrorBoundary - 调用以重设 ErrorBoundary 状态

后退会使任何时间 ErrorBoundary 抓取错误。 没错 有用以有一个倒置的 UI 来优雅地处理您的用户的错误,同时 仍然在幕后向 BugSplat 发送错误 .

ErrorBoundary 接受一个 resetKeys 您可以通过一系列 如果其中之一值发生变化,则会使其自动重置的值. 这给了你从外部控制错误状态的权力 组件.

function App() {
  const [error, setError] = useState<Error | null>();

  return (
    <ErrorBoundary
      fallback={(props) => <Fallback {...props} />}
      onReset={() => setError(null)}
      resetKeys={[error]}
    >
      {}
    </ErrorBoundary>
  );
}

用户反馈

想要收集用户反馈, 如标题、描述和文件 附件吗? 使用 useFeedback 键入直接向您提交反馈 BugSplate仪表板.

// src/FeedbackForm.tsx

import { useState } from 'react';
import { useFeedback } from '@bugsplat/react';

export default function FeedbackForm() {
  const [title, setTitle] = useState('');
  const [description, setDescription] = useState('');
  const [files, setFiles] = useState<FileList | null>(null);
  const { postFeedback, loading, response, error } = useFeedback();

  const handleSubmit = async (e: React.FormEvent) => {
    e.preventDefault();

    const attachments = files
      ? Array.from(files).map((file) => ({ filename: file.name, data: file }))
      : [];

    await postFeedback(title, { description, attachments });
  };

  if (response) {
    return <p>Thanks for your feedback!</p>;
  }

  return (
    <form onSubmit={handleSubmit}>
      <input
        type="text"
        placeholder="Title"
        value={title}
        onChange={(e) => setTitle(e.target.value)}
      />
      <textarea
        placeholder="Description"
        value={description}
        onChange={(e) => setDescription(e.target.value)}
      />
      <input
        type="file"
        multiple
        onChange={(e) => setFiles(e.target.files)}
      />
      <button type="submit" disabled={loading}>
        {loading ? 'Submitting...' : 'Send Feedback'}
      </button>
      {error && <p>{error.message}</p>}
    </form>
  );
}

高级使用

这个 scope 属性

如果你知道自己在做什么 想要错误的功能 除了通过道具和召回可能做到的以外,你可以扩展 BugSplate 客户端并通过它传递到错误边界 scope 属性.

import { BugSplat } from 'bugsplat';
import { ErrorBoundary } from '@bugsplat/react';
import SomeService from '@some/service';

class CustomBugSplatClient extends BugSplat {
  async post(error: CustomError) {
    await SomeService.post(error);

    return super.post(error);
  }
}

const client = new CustomBugSplatClient();

function App() {
  <ErrorBoundary scope={{ getClient: () => client }}>
    <ChildComponents />
  </ErrorBoundary>;
}

API 密码

init()

interface BugSplatInit {
  /**
   * BugSplat database name that crashes should be posted to
   */
  database: string;
  /**
   * Name of application
   */
  application: string;
  /**
   * Version of application.
   */
  version: string;
}

/**
 * Initialize a new BugSplat instance and store the reference in scope
 *
 * @returns function with a callback argument that will be
 * called with the freshly initialized BugSplat instance
 *
 * - Useful to subscribe to events or set default properties
 */
export function init({
  database,
  application,
  version,
}: BugSplatInit): (initializer: (client: BugSplat) => void) => void;

/**
 * @example
 */
init({
  database: 'fred',
  application: 'my-react-crasher',
  version: '3.2.1',
})((bugSplat) => {
  bugSplat.setDefaultAppKey('Key!');
  bugSplat.setDefaultUser('User!');
  bugSplat.setDefaultEmail('[email protected]');
  bugSplat.setDefaultDescription('Description!');
});

getBugSplat()

/**
 * Get `BugSplat` instance from application scope
 */
const getBugSplat: () => BugSplat | null;

ErrorBoundary

interface FallbackProps {
  /**
   * Error that caused crash
   */
  error: Error;
  /**
   * Component stack trace leading to error
   */
  componentStack: string | null;
  /**
   * Crash post response
   */
  response: BugSplatResponse | null;
  /**
   * Reset error boundary state.
   *
   * This will pass any arguments to the end of onReset when it is called
   */
  resetErrorBoundary: (...args: unknown[]) => void;
}

type FallbackElement = ReactElement | null;

type FallbackRender = (props: FallbackProps) => FallbackElement;

/**
 * All props in ErrorBoundaryProps are optional,
 * but we recommend at least setting the fallback prop.
 */
interface ErrorBoundaryProps {
  /**
   * Callback called before error post to BugSplat.
   *
   * This will be awaited if it is a promise
   */
  beforePost: (
    bugSplat: BugSplat,
    error: Error | null,
    componentStack: string | null
  ) => void | Promise<void>;

  /**
   * Callback called when ErrorBoundary catches an error in componentDidCatch()
   *
   * This will be awaited if it is a promise
   */
  onError: (
    error: Error,
    componentStack: string,
    response: BugSplatResponse | null
  ) => void | Promise<void>;

  /**
   * Callback called on componentDidMount().
   */
  onMount: () => void;

  /**
   * Callback called on componentWillUnmount().
   */
  onUnmount: (state: ErrorBoundaryState) => void;

  /**
   * Callback called before ErrorBoundary resets internal state,
   * resulting in rendering children again. This should be
   * used to ensure that rerendering of children would not
   * repeat the same error that occurred.
   *
   * *This method is not called when ErrorBoundary is reset from a
   * change in resetKeys - use onResetKeysChange for that.*
   * @param state - Current error boundary state
   * @param ...args - Additional arguments passed from where it is called
   */
  onReset: (state: ErrorBoundaryState, ...args: unknown[]) => void;

  /**
   * Callback called when keys passed to resetKeys are changed.
   */
  onResetKeysChange: (prevResetKeys?: unknown[], resetKeys?: unknown[]) => void;

  /**
   * Array of values passed from parent scope. When ErrorBoundary
   * is in an error state, it will check each passed value
   * and automatically reset if any of the values have changed.
   */
  resetKeys?: unknown[];

  /**
   * Provide a fallback to render when ErrorBoundary catches an error.
   * Not required, but it is highly recommended to provide a value for this.
   *
   * This can be an element or a function that renders an element.
   */
  fallback?: FallbackElement | FallbackRender;

  /**
   * If true, caught errors will not be automatically posted to BugSplat.
   */
  disablePost?: boolean;

  /**
   * Child elements to be rendered when there is no error
   */
  children?: ReactNode | ReactNode[];

  /**
   * __Advanced Use__
   *
   * Object used by ErrorBoundary to retrieve a BugSplat client instance.
   *
   * Advanced users can extend the `BugSplat` class and use this property
   * to pass their own scope that will inject the client for use by
   * ErrorBoundary.
   */
  scope: { getClient(): BugSplat | null };
}

interface ErrorBoundaryState {
  error: Error | null;
  componentStack: string | null;
  response: BugSplatResponse | null;
}

/**
 * Handle errors that occur during rendering by wrapping
 * your component tree with ErrorBoundary. Any number of ErrorBoundary
 * components can be rendered in the tree and any rendering error will
 * propagate to the nearest one.
 */
class ErrorBoundary extends Component<
  ErrorBoundaryProps,
  ErrorBoundaryState
>

withErrorBoundary

/**
 * Higher order component to wrap your component tree with ErrorBoundary
 */
function withErrorBoundary<P extends Record<string, unknown>>(
  Component: ComponentType<P>,
  errorBoundaryProps: ErrorBoundaryProps = {}
): ComponentType<P>;

useErrorHandler

/**
 * Utility hook to declaratively or imperatively propagate an
 * error to the nearest error boundary.
 *
 * *Should be called from a child of ErrorBoundary*
 *
 * Propagate error:
 *
 * * Declaratively - by passing an error prop
 * * Imperatively - by calling the returned handler with an error
 *
 * @param errorProp - Will throw when a truthy value is passed
 * @returns Error handler that will throw when called with a truthy value
 */
function useErrorHandler(errorProp?: unknown): (error: unknown) => void;

useFeedback

/**
 * Hook for submitting user feedback to BugSplat.
 *
 * @returns Object with `postFeedback` function and `loading`/`response`/`error` state
 *
 * @example
 * const { postFeedback, loading, error } = useFeedback();
 * await postFeedback('Login button broken', { description: 'Nothing happens when I tap it' });
 */
function useFeedback(): {
  /**
   * Submit user feedback to BugSplat.
   *
   * @param title - Feedback title
   * @param options - Optional BugSplat options (description, attachments, etc.)
   */
  postFeedback: (title: string, options?: BugSplatOptions) => Promise<void>;
  /**
   * Whether feedback is currently being submitted
   */
  loading: boolean;
  /**
   * BugSplat response from the most recent feedback submission
   */
  response: BugSplatResponse | null;
  /**
   * Error from the most recent feedback submission, if any
   */
  error: Error | null;
};

测试套件

这个包包既包括单元测试,也包括集成测试. 为了管理他们, 使用提供的软件包。json脚本.

测试命令
单位npm run test
一体化npm run test:integration

版本与发布记录

@bugsplat/react 共发布 6 个版本,首次发布于 2022/07/27;过去 12 个月发布了 3 个版本。

版本发布日期距今
2.1.1latest2026/04/196 个月前
2.1.02026/04/186 个月前
2.0.02026/03/177 个月前
1.0.32022/09/094 年前
1.0.22022/09/074 年前
1.0.12022/07/274 年前

关于 @bugsplat/react 的常见问题

@bugsplat/react 是什么?

用于反应的 bugsplay 工具

如何安装 @bugsplat/react?

在项目目录运行 npm install @bugsplat/react,或使用 pnpm add / yarn add / bun add。它还需要宿主项目提供 peer 依赖:react(^19.0.0)、react-dom(^19.0.0)。npm 7 及以上与 pnpm 8 及以上默认会自动安装必需的 peer 依赖,Yarn 需要手动安装。

@bugsplat/react 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@bugsplat/react 支持 ESM 还是 CommonJS?

以 CommonJS 形式发布,可以直接 require();在 ES Module 项目中也可以用 import 引入(Node.js 会把 module.exports 作为默认导出)。

@bugsplat/react 可以商用吗?

@bugsplat/react 使用 MIT 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@bugsplat/react 的下载量有多少?

根据 npm 官方下载统计,@bugsplat/react 在 2026/10/09 – 2026/11/07 这 30 天内被下载 3,016 次,日均约 101 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@bugsplat/react 还在维护吗?

最新版本 2.1.1 发布于 2026/04/19(6 个月前);至今共发布 6 个版本,其中过去 12 个月发布了 3 个;首次发布于 2022/07/27。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。