React#

许多 JupyterLab API 需要 Lumino Widgets,它们比原生 DOM 元素具有更多功能,包括

  • 向下传播到 Widget 层次的调整大小事件。

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

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

我们支持使用 @jupyterlab/ui-components 中的 ReactWidget 类将 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-components 中的 UseSignal 组件,它实现了 “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 - Static Typing Guide” 中关于在 TypeScript 中使用 React 的最佳实践。