React#

许多 JupyterLab API 都需要 Lumino Widgets,与原生 DOM 元素相比,它们具有一些额外的特性,包括:

  • 在 Widget 层次结构中传播的尺寸调整事件。

  • 生命周期事件(onBeforeDetachonAfterAttach 等)。

  • 基于 CSS 和绝对定位的布局。

我们支持使用来自 @jupyterlab/ui-componentsReactWidget 类,将 React 组件包装成 Lumino 小部件。

/*
 * Copyright (c) Jupyter Development Team.
 * Distributed under the terms of the Modified BSD License.
 */

import * as React from 'react';

import { Widget } from '@lumino/widgets';
import { ReactWidget } from '@jupyterlab/ui-components';

function MyComponent() {
  return <div>My Widget</div>;
}

const myWidget: Widget = ReactWidget.create(<MyComponent />);
Widget.attach(myWidget, document.body);

这里我们使用 create 静态方法将一个 React 元素转换为 Lumino 小部件。每当小部件被挂载时,React 元素都会在页面上渲染。

如果您需要在 Lumino 小部件上处理其他生命周期事件或向其添加其他方法,您可以继承 ReactWidget 并重写 render 方法以返回一个 React 元素。

/*
 * Copyright (c) Jupyter Development Team.
 * Distributed under the terms of the Modified BSD License.
 */

import * as React from 'react';

import { Widget } from '@lumino/widgets';
import { ReactWidget } from '@jupyterlab/ui-components';

function MyComponent() {
  return <div>My Widget</div>;
}
class MyWidget extends ReactWidget {
  render() {
    return <MyComponent />;
  }
}
const myWidget: Widget = new MyWidget();
Widget.attach(myWidget, document.body);

我们使用 Lumino Signals 来表示 JupyterLab 中随时间变化的数据。要让您的 React 元素响应信号事件而变化,请使用来自 @jupyterlab/ui-componentsUseSignal 组件,该组件实现了 “render props”

/*
 * Copyright (c) Jupyter Development Team.
 * Distributed under the terms of the Modified BSD License.
 */

import * as React from 'react';

import { ReactWidget, UseSignal } from '@jupyterlab/ui-components';

import { ISignal, Signal } from '@lumino/signaling';

import { Widget } from '@lumino/widgets';

function MyComponent() {
  return <div>My Widget</div>;
}

function UseSignalComponent(props: { signal: ISignal<MyWidget, void> }) {
  return <UseSignal signal={props.signal}>{() => <MyComponent />}</UseSignal>;
}

class MyWidget extends ReactWidget {
  render() {
    return <UseSignalComponent signal={this._signal} />;
  }

  private _signal = new Signal<this, void>(this);
}

const myWidget: Widget = new MyWidget();
Widget.attach(myWidget, document.body);

运行组件搜索覆盖层 中的 createSearchOverlay 函数都使用了这些特性,并且可以作为最佳实践的良好参考。

在 JupyterLab 扩展示例仓库 中还有一个 简单示例,用于创建 Lumino react 小部件。

我们目前还没有将 Lumino 小部件嵌入 React 组件的方法。如果您发现自己正在尝试这样做,我们建议将 Lumino 小部件转换为 React 组件,或者将 Lumino 小部件用于外部层组件。

我们遵循 React 文档“React & Redux in TypeScript - 静态类型指南”,以获取在 TypeScript 中使用 React 的最佳实践。