如何将普通的javascript重写成反应组件(foreach)

时间:2018-05-22 18:45:51

标签: javascript reactjs typescript

我有以下spfx组件,它是普通的javascript并且工作得很好。

import { Version } from '@microsoft/sp-core-library';
import {
  BaseClientSideWebPart,
  IPropertyPaneConfiguration,
  PropertyPaneTextField
} from '@microsoft/sp-webpart-base';
import { escape } from '@microsoft/sp-lodash-subset';

import styles from './MyQuotesWebPart.module.scss';
import * as strings from 'MyQuotesWebPartStrings';

import { IQuotes, IQuote } from './QuoteContracts';
import { IDataReader, DataReaderFactory } from './DataReader';

export interface IMyQuotesWebPartProps {
  description: string;
}

export default class MyQuotesWebPart extends BaseClientSideWebPart<IMyQuotesWebPartProps> {

  constructor() {
    super();
    this._dataReader = DataReaderFactory.getReader(this.context);
  }

  private _dataReader : IDataReader;

  public render(): void {
    this.domElement.innerHTML = `
      <div class="${styles.myQuotes}">
        <div class="${styles.container}">
          <div class="ms-Grid-row ms-bgColor-themeDark ms-fontColor-white ${styles.row}">
            <div class="ms-Grid-col ms-lg10 ms-xl8 ms-xlPush2 ms-lgPush1">
              <span class="ms-font-xl ms-fontColor-white">Famous Quotes</span>
              <div class="ms-font-l ms-fontColor-white" id="quotesContainer"></div>
            </div>
          </div>
        </div>
      </div>`;

      this.renderData();
  }

  protected get dataVersion(): Version {
    return Version.parse('1.0');
  }

  protected getPropertyPaneConfiguration(): IPropertyPaneConfiguration {
    return {
      pages: [
        {
          header: {
            description: strings.PropertyPaneDescription
          },
          groups: [
            {
              groupName: strings.BasicGroupName,
              groupFields: [
                PropertyPaneTextField('description', {
                  label: strings.DescriptionFieldLabel
                })
              ]
            }
          ]
        }
      ]
    };
  }

  private renderData(): void {
    this._dataReader.getData().then((response) => {
      this.renderQuotes(response.Quotes);
    });
  }

  private renderQuotes(items: IQuote[]): void {
    let html: string = '';
    items.forEach((item: IQuote) => {
      html += `
        <div>${escape(item.Quote)}</div>
        <div class="${styles.author}">${escape(item.Author)}</div>  
      `;
    });

    const listContainer: Element = this.domElement.querySelector('#quotesContainer');
    listContainer.innerHTML = html;
  }
}

我正在尝试创建一个react组件,但我不确定如何使用渲染数据以及如何在结果集中使用foreach来渲染它,基本上问题是如何将它集成到render方法中

import * as React from 'react';
import styles from './Solid.module.scss';
import { ISolidProps } from './ISolidProps';
import { escape } from '@microsoft/sp-lodash-subset';
import { IQuotes, IQuote } from './QuoteContracts';
import { IDataReader, DataReaderFactory } from './DataReader';


export default class Solid extends React.Component<ISolidProps, {}> {

  constructor() {
    super();
    this._dataReader = DataReaderFactory.getReader(this.context);
  }

  private _dataReader : IDataReader;

  public render(): React.ReactElement<ISolidProps> {
    return (
      <div className={ styles.solid }>
        <div className={ styles.container }>
          <div className={ styles.row }>
            <div className={ styles.column }>
              <span className={ styles.title }>Welcome to SharePoint!</span>
              <p className={ styles.subTitle }>Customize SharePoint experiences using Web Parts.</p>
              <p className={ styles.description }>{escape(this.props.description)}</p>
              <a href="https://aka.ms/spfx" className={ styles.button }>
                <span className={ styles.label }>Learn more</span>
              </a>
            </div>
          </div>
        </div>
      </div>
    );
  }
}

更新1:

我有这样的界面:

export interface IQuotes {
    Quotes: IQuote[];
}

export interface IQuote {
    Author: string;
    Quote: string;
}

1 个答案:

答案 0 :(得分:2)

由于获取数据的请求将是异步的,因此您应该将其作为React组件的成员函数,如下所示:

{% extends 'pictures/base.html' %}
{% block title %}publish{% endblock %}
{% block content %}
  <form class="form" action="" method="post">
    {% csrf_token %}
    {{ form }}
    <input type="submit" value="Submit">
  </form>
{% endblock %}

这将在调用方法时触发渲染,除非您阻止fetchData = () => { this._dataReader.getData().then((response) => { this.setState({ quotes: response.Quotes, }); }); } 中的更新。然后我们可以为引号实现renderMethod:

shouldComponentUpdate

您不必使用renderQuotes = () => this.state.quotes.map(quote => ( <React.Fragment> <div>${escape(quote.Quote)}</div> <div class="${styles.author}">${escape(quote.Author)}</div> </React.Fragment> ); ,因为它是React 16.3的一部分,它在这里很有用。

然后可以渲染主渲染方法

Fragment

并在<div> {this.renderQuotes()} </div> 中,您可以发出网络请求等。您可以拨打componentDidMount

fetchData