1

This is the origin example I tried to imlement with Spfx&reactJs webpart. it looks working except when I edit the account(in editor pane), it doesnt affected till I reload the webpart also tweet limit not works.

webpart.tsx:

export default class Twitter extends React.Component<ITwitterProperties, IWebPartState> {
  private twttr: any;
  public render(): JSX.Element {
    debugger
    var innerHtml:any;
    if (this.props.account == null || this.props.account == '' || this.props.account == undefined) {
      var error = `
        <div class="ms-MessageBar">
          <div class="ms-MessageBar-content">
            <div class="ms-MessageBar-icon">
              <i class="ms-Icon ms-Icon--Info"></i>
            </div>
            <div class="ms-MessageBar-text">
              ${strings.ErrorSelectAccount}
            </div>
          </div>
        </div>
      `;
      innerHtml=error;
    }
    else
    {
    var dataChrome = '';
    if (this.props.footer === false)
      dataChrome += "nofooter ";
    if (this.props.header === false)
      dataChrome += "noheader ";
    if (this.props.borders === false)
      dataChrome += "noborders ";
    if (this.props.scrollbars === false)
      dataChrome += "noscrollbar ";
    if (this.props.transparent === true)
      dataChrome += "transparent ";
    var limit = '';
    if (this.props.autoLimit === false)
      limit = 'data-tweet-limit="' + this.props.limit + '"';

    innerHtml = '<a class="twitter-timeline" data-link-color="' + this.props.linkColor + '" data-border-color="' + this.props.borderColor + '" height="' + this.props.height + '" width="' + this.props.width + '" ' + limit + ' data-chrome="' + dataChrome + '" href="https://twitter.com/' + this.props.account + '">Tweets by ' + this.props.account + '</a>';

    if (this.twttr == null) {
      SPComponentLoader.loadScript('//platform.twitter.com/widgets.js', { globalExportsName: 'twttr' }).then((twttr?: any)=> {
        this.twttr = twttr;
      });
    }
    else {
      this.twttr.widgets.load();
    }
    }

     return (
      <div dangerouslySetInnerHTML={{__html: innerHtml}}>
      </div>
    );
  }
}

webpart.ts:

export default class TwitterWebPart extends BaseClientSideWebPart<ITwitterProps> {
public constructor(context?: IWebPartContext) {
    super();

    //Hack: to invoke correctly the onPropertyChange function outside this class
    //we need to bind this object on it first
    this.onPropertyPaneFieldChanged = this.onPropertyPaneFieldChanged.bind(this);
  }

  public render(): void {
    const element: React.ReactElement<ITwitterProperties> = React.createElement(

      Twitter,
      {
        httpClient: this.context.spHttpClient,
        siteUrl: this.context.pageContext.web.absoluteUrl,
        listName: "Messages",//announcement2
        account: this.properties.account,
        autoLimit:this.properties.autoLimit,
        limit:this.properties.limit,
        header:this.properties.header, 
        footer:this.properties.footer,
        borders: this.properties.borders,
        scrollbars: this.properties.scrollbars, 
        width:this.properties.width,
        height:this.properties.height,
        transparent:this.properties.transparent,
        dark:this.properties.dark,
        linkColor:this.properties.linkColor,
        borderColor:this.properties.borderColor,
        description:this.properties.description
      }
    );
    ReactDom.render(element, this.domElement);
  }

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

  protected getPropertyPaneConfiguration(): IPropertyPaneConfiguration {
    return {
      pages: [
        {
          header: {
            description: strings.PropertyPaneDescription
          },
          displayGroupsAsAccordion: true,
          groups: [
            {
              groupName: strings.BasicGroupName,
              groupFields: [
                PropertyPaneTextField('account', {
                  label: strings.Account
                }),
                PropertyPaneToggle('autoLimit', {
                  label: strings.AutoLimit
                }),
                PropertyPaneSlider('limit', {
                  label: strings.Limit,
                  min: 1,
                  max: 1000,
                  step: 1
                }),
                PropertyPaneToggle('header', {
                  label: strings.Header
                }),
                PropertyPaneToggle('footer', {
                  label: strings.Footer
                }),
                PropertyPaneToggle('borders', {
                  label: strings.Borders
                }),
                PropertyPaneToggle('scrollbars', {
                  label: strings.Scrollbars
                })
              ]
            },
            {
              groupName: strings.LayoutGroupName,
              groupFields: [
                PropertyPaneTextField('width', {
                  label: strings.Width
                }),
                PropertyPaneTextField('height', {
                  label: strings.Height
                }),
                PropertyPaneToggle('transparent', {
                  label: strings.Transparent
                }),
                PropertyFieldColorPicker('linkColor', {
                  label: strings.LinkColor,
                  initialColor: this.properties.linkColor,
                  onPropertyChange: this.onPropertyPaneFieldChanged,
                  properties: this.properties
                }),
                PropertyFieldColorPicker('borderColor', {
                  label: strings.BorderColor,
                  initialColor: this.properties.borderColor,
                  onPropertyChange: this.onPropertyPaneFieldChanged,
                  properties: this.properties
                })
              ]
            }
          ]
        }
      ]
    };
  }
}

This is my repo. if you think its necessary,(webpart:twitter)

1 Answer 1

2

You can take a look at implementing mobx with your React webpart.

React renders the application state by providing mechanisms to translate it into a tree of renderable components. MobX provides the mechanism to store and update the application state that React then uses.

Reference - Mobxjs

Here is one sample SPFx implementation that uses Mobx

Reference link - SPFx React Mobx - currently on drop 5, but you can use it in RC 0 after making some necessary adjustments.

You will have to install the Mobx and its react-bindings as below:

npm install mobx --save
npm install mobx-react --save

After that in your tsx file, you need to make the below entries:

import { Provider } from 'mobx-react';

import * as strings from 'reactMobxStrings';
import DefaultContainer from './containers/DefaultContainer';
import { IReactMobxWebPartProps } from './IReactMobxWebPartProps';
import twitter from './twitter';  //make necessary changes here

After that your class would look something as below, note this part is not totally accurate as I could not find twitter webpart in your git repository(please upload if possible) , make changes as necessary as per sample SPFx webpart :

export default class TwitterWebPart extends BaseClientSideWebPart<ITwitterProps> { 
  private twitter = new twitter();

  public constructor(context: IWebPartContext) {
    super(context);
  }

  public render(): void {
    if (this.renderedOnce) { return; }

    const element  = (

      <Provider {...this.Twitter}>
      {
        httpClient: this.context.spHttpClient,
        siteUrl: this.context.pageContext.web.absoluteUrl,
        listName: "Messages",//announcement2
        account: this.properties.account,
        autoLimit:this.properties.autoLimit,
        limit:this.properties.limit,
        header:this.properties.header, 
        footer:this.properties.footer,
        borders: this.properties.borders,
        scrollbars: this.properties.scrollbars, 
        width:this.properties.width,
        height:this.properties.height,
        transparent:this.properties.transparent,
        dark:this.properties.dark,
        linkColor:this.properties.linkColor,
        borderColor:this.properties.borderColor,
        description:this.properties.description
      }
      </Provider>
    );
    ReactDom.render(element, this.domElement);    
  }

  protected get disableReactivePropertyChanges() {
    return this.properties ? this.properties.disableReactive : false;
  }

  protected onPropertyChanged(propertyPath, oldValue, newValue) {
    if (!this.disableReactivePropertyChanges) {
      this.twitter.webpart.properties.set(propertyPath, newValue);
    }
  }

  protected onInit() {
    this.twitter.webpart.properties.clear();
    this.twitter.webpart.properties.merge(this.properties as {});

    return Promise.resolve(true);
  }

  protected onAfterPropertyPaneChangesApplied() {
    this.twitter.webpart.properties.merge(this.properties as {});
  }

  //code here
}

Also read this link - Building SharePoint Framework Client Side Web Parts with non-reactive property pane

2
  • welcome , FYI i cloned your repository , couldnt find twitter webpart ? did you publish it ? Commented Feb 10, 2017 at 9:10
  • Yes. it was belong to other branch but I merge it with master. Can you check it now ? Commented Feb 10, 2017 at 10:47

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.