如何将tsx导入SPFx扩展

时间:2018-02-05 17:02:51

标签: reactjs typescript sharepoint tsx

我刚刚开始了我的第一个SharePoint项目,但无法弄清楚如何在我的扩展中使用我的React组件。以下是相关文件。

Navbar.tsx:

import * as React from "react";
export const Navbar = props => <div>Hello world</div>;

ReactSharePointNavbarApplicationCustomizer.tsx:

import { override } from "@microsoft/decorators";
import { Log } from "@microsoft/sp-core-library";
import {
  BaseApplicationCustomizer,
  PlaceholderContent,
  PlaceholderName
} from "@microsoft/sp-application-base";
import { Dialog } from "@microsoft/sp-dialog";

import * as strings from "ReactSharePointNavbarApplicationCustomizerStrings";

import styles from "./AppCustomizer.module.scss";
import { escape } from "@microsoft/sp-lodash-subset";

import * as Components from "./components";
import Navbar = Components.Navbar;

const LOG_SOURCE: string = "ReactSharePointNavbarApplicationCustomizer";

/**
 * If your command set uses the ClientSideComponentProperties JSON input,
 * it will be deserialized into the BaseExtension.properties object.
 * You can define an interface to describe it.
 */

export interface IReactSharePointNavbarApplicationCustomizerProperties {}

/** A Custom Action which can be run during execution of a Client Side Application */
export default class ReactSharePointNavbarApplicationCustomizer extends BaseApplicationCustomizer<
  IReactSharePointNavbarApplicationCustomizerProperties
> {
  private _onDispose(): void {
    console.log("No place holder.");
  }
  private _topPlaceholder: PlaceholderContent | undefined;
  private _renderPlaceHolders(): void {
    if (!this._topPlaceholder) {
      this._topPlaceholder = this.context.placeholderProvider.tryCreateContent(
        PlaceholderName.Top,
        { onDispose: this._onDispose }
      );

      if (!this._topPlaceholder) {
        return;
      }

      if (this.properties) {
        const Nav = Navbar(null);

        if (this._topPlaceholder.domElement) {
          this._topPlaceholder.domElement.innerHTML = `
            <div class="${styles.app}">
              <div class="ms-bgColor-themeDark ms-fontColor-white ${
                styles.top
              }">
               ${Nav}
               ${Navbar}
               <div>Hello</div>
              <Navbar/>
              </div>
            </div>`;
        }
      }
    }
  }

  @override
  public onInit(): Promise<void> {
    Log.info(LOG_SOURCE, `Initialized ${strings.Title}`);

    // Added to handle possible changes on the existence of placeholders.
    this.context.placeholderProvider.changedEvent.add(
      this,
      this._renderPlaceHolders
    );

    // Call render method for generating the HTML elements.
    this._renderPlaceHolders();
    return Promise.resolve<void>();
  }
}

成分:

export * from "./Navbar";

我的目标是使用我的反应组件作为导航栏,但是我无法在这种情况下将tsx和ts结合起来。

我遵循了这个指南:https://docs.microsoft.com/en-us/sharepoint/dev/spfx/extensions/get-started/using-page-placeholder-with-extensions

在这些文件之外,我所做的唯一修改是添加一个组件文件夹,其中包含您在上面看到的组件和索引。

请帮我解决这个挑战。

1 个答案:

答案 0 :(得分:0)

经过几个小时的研究,我找到了解决方案。我是以错误的方式来的,我需要使用ReactDOM来插入我的TSX组件。之后React开发正常。不需要像以前那样尝试以某种奇特的方式插入元素。

这是工作代码。

<强> ReactSharePointNavbarApplicationCustomizer.ts

import * as React from "react";
import * as ReactDOM from "react-dom";
import { override } from "@microsoft/decorators";
import { Log } from "@microsoft/sp-core-library";
import {
  BaseApplicationCustomizer,
  PlaceholderContent,
  PlaceholderName
} from "@microsoft/sp-application-base";

import { Dialog } from "@microsoft/sp-dialog";

import * as strings from "ReactSharePointNavbarApplicationCustomizerStrings";

import styles from "./AppCustomizer.module.scss";
import { escape } from "@microsoft/sp-lodash-subset";

import Navbar, { INavbarProps } from "./components/Navbar";

const LOG_SOURCE: string = "ReactSharePointNavbarApplicationCustomizer";

export interface IReactSharePointNavbarApplicationCustomizerProperties {}

export default class ReactSharePointNavbarApplicationCustomizer extends BaseApplicationCustomizer<
  IReactSharePointNavbarApplicationCustomizerProperties
> {
  private _onDispose(): void {}

  private onRender(): void {
    const header: PlaceholderContent = this.context.placeholderProvider.tryCreateContent(
      PlaceholderName.Top,
      {
        onDispose: this._onDispose
      }
    );
    if (!header) {
      Log.error(LOG_SOURCE, new Error("Could not find placeholder PageHeader"));
      return;
    }

    const elem: React.ReactElement<INavbarProps> = React.createElement(Navbar);
    ReactDOM.render(elem, header.domElement);
  }

  @override
  public onInit(): Promise<void> {
    this.onRender();
    return Promise.resolve<void>();
  }
}

<强> Navbar.tsx

import * as React from "react";
import styles from "./Navbar.module.scss";

import NavbarItem from "../NavbarItem";

export interface INavbarProps {}

export default class Navbar extends React.Component<INavbarProps> {
  constructor(props: INavbarProps) {
    super(props);
  }

  public render(): JSX.Element {
    return (
      <div className={"ms-bgColor-themeDark ms-fontColor-white " + styles.nav}>
        Hello world
      </div>
    );
  }
}

如您所见,components.ts导出文件是不必要的。我确信其他代码在这些示例中可能仍然无用。

我发现将tsx组件导入其他tsx组件就像普通的React导入一样。只需导入并插入元素即可。