SharePoint Framework aka SPFx Web Part Using React And REST API

The SharePoint Framework (SPFx) provides full support for client-side SharePoint development. This provides easy integration with SharePoint data. It is compatible with modern technologies and tool. You can use your own IDE no need to purchase Visual Studio. Moreover SPFx is responsive in design. This article talks about using the SharePoint Framework web part with React as Framework. The whole article will walk you through the complete lifecycle from Pre Requisite , Understanding SPFx Web Part, Configure, Build & Deploy.

Introduction
 
The SharePoint Framework (SPFx) provides full support for client-side SharePoint development. This provides easy integration with SharePoint data. It is compatible with modern technologies and tools. You can use your own IDE; there's  no need to purchase Visual Studio. Moreover, SPFx is responsive in design.
 
This article talks about using the SharePoint Framework web part with React as Framework. The whole article will walk you through the complete lifecycle from prerequisites to understanding SPFx Web Part, configuring it, building and deploying an application.
 
Using the code
 
The code uses React to do the rendering part on the SharePoint Page. REST API fetches the data from the SharePoint list. The data source gets refreshed at a particular interval of time. The page only gets updated if there is a change in the data values as compared to current DOM. No need to refresh the page to see updated data. As soon as the state changes, React does the job of updating DOM.
 
Prerequisites
 
Below are the prerequisites from an installation and learning point of view. References are provided for installation links below. You will also need to create a SharePoint Developer & AppCatalog site, these will come handy while deploying the code. Don't forget to create the SharePoint list with columns as shown below.
 
Installation
 
Node.js & npm - https://nodejs.org/en/download
 
Yeoman & gulp - Open command prompt as administrator. Use below command to install gulp and yeoman.
  1. npm install -g yo gulp  
Visual Studio Code - https://code.visualstudio.com/docs/setup/windows
 
Create App Catalog & Developer Site
 
AppCatalog - Go to SharePoint Admin Site. Then go to Apps you will see an option to create an app catalog site.
Developer Site - Go to https://yourtenannt.sharepoint.com/_layouts/15/online/SiteCollections.aspx
 
Create SharePoint List
 
Create SharePoint list using below columns of type text.
 
SharePoint Framework aka SPFx Web Part Using React And REST API
Create SPFX Web Part
 
Once the installation of all the required components is completed, it's time to create SPFx webpart. Run the below command and select options as displayed in below screen. This command initiates yeoman to start creating a SharePoint web part.
  1. yo @microsoft/sharepoint  
 SharePoint Framework aka SPFx Web Part Using React And REST API
 
Install jQuery 
  1. npm install --save jquery  
  2. npm install --save @types/jquery  
 Understanding SPFx WebPart File Structure
 
Open the newly created solution in VS Code using code . in the command prompt. There are many files in the whole solution. Below are the important files which we will talk about throughout the article.
 
SharePoint Framework aka SPFx Web Part Using React And REST API 
 
Sanity check
 
Let’s check if the solution builds using gulp. Run the below command in your command prompt window. Make sure you are in the directory where the web part is created.
gulp build
 
The solution builds, let’s start understanding and updating files in the solution.
 
ReactGetItems.module.scss
 
This is like CSS file for SPFx web part. Overwrite your file with the below code.
  1. .tableStyle{    
  2.     display:  table ;  
  3.     margin-left :  50px ;  
  4. }  
  5. .panelStyle{    
  6.    background:  white ;  
  7. }  
  8.   
  9. .divStyle{  
  10. background:  #eee ;  
  11. padding:  20px ;  
  12. margin:  20px ;  
  13. }  
  14.   
  15. .headerCaptionStyle{  
  16. background:  white ;  
  17. display:  table-row ;  
  18.     border:  solid ;  
  19.     text-align :  center ;  
  20.     width :  420px ;  
  21.     height :  30px ;  
  22.     padding-top :  3px ;  
  23.     color :  white ;  
  24.     margin-left :  100px ;  
  25.     display :  block ;  
  26. }  
  27.   
  28. .headerStyle{  
  29. background:  #4B6978 ;  
  30. display:  table-row ;  
  31.     border:  solid ;  
  32.     text-align :  center ;  
  33.     width :  100px ;  
  34.     height :  30px ;  
  35.     padding-top :  10px ;  
  36.     color :  white ;  
  37. }  
  38.   
  39. .tableCaptionStyle{  
  40. background:#4B6978 ;  
  41. display:  block ;  
  42. font-size :  20px ;  
  43. font-weight:  bold ;   
  44.     border:  solid ;  
  45.     text-align :  center ;  
  46.     width :  650px ;  
  47.     height :  30px ;  
  48.     padding-top :  3px ;  
  49.     border-radius:  25px ;  
  50.     margin-left :  30px ;  
  51.     margin-top :  20px ;  
  52.     color:white;  
  53. }  
  54.   
  55. .rowCaptionStyle{  
  56. width :  600px ;  
  57. display :   table-caption ;  
  58. background:  #4B6978 ;  
  59. text-align :  center ;  
  60. padding:  20px ;  
  61. font-size :  20px ;  
  62. font-weight : bold ;  
  63. color :  white ;  
  64. }  
  65.   
  66. .rowStyle{  
  67. display :   table-row ;  
  68. background:  #eee ;  
  69. padding:  20px ;  
  70. margin:  20px ;  
  71. font-weight : bold ;  
  72. }  
  73.   
  74. .CellStyle{    
  75.     display:  table-cell ;   
  76.     border:  solid ;  
  77.      border-color :  white ;  
  78.     text-align :  center ;  
  79.     width :  100px ;  
  80.     height :  30px ;  
  81.     padding-top :  10px ;  
  82.       
  83. }  
IReactSpfxWebPartProps.ts
 
Let’s update our IReactSpfxWebPartProps.ts. This is our interface for React.
 
Siteurl property is used for passing the site in context to webpart. Description is the description of your webpart.
  1. export interface IReactSpfxWebPartProps {  
  2.   description: string;  
  3.   siteurl: string;  
  4. }  
ReactSpFxWebPart.tsx
 
This is the most important file which is generated as we chose React Framewrok. Overwrite the files in your solution with the below code,
  • IReactSpfxState - Interface for the state
  • ReactGetItems - Class File
  • constructor - Intitalizes State
  • componentDidMount - React Component
  • fetchDatafromSharePointList - This method uses REST API to fetch data
  • render - Rendering the html
  1. import * as React from 'react';  
  2. import styles from './ReactSpfxWebPart.module.scss';  
  3. import { IReactSpfxWebPartProps } from './IReactSpfxWebPartProps';  
  4. import * as jquery from 'jquery';  
  5.   
  6. export interface IReactSpfxState{    
  7.   items:[    
  8.         {    
  9.           "Courses""",   
  10.           "Credit""",   
  11.           "Department":"",  
  12.         }]    
  13. }    
  14.   
  15. export default class ReactGetItems extends React.Component<IReactSpfxWebPartProps, IReactSpfxState> {  
  16.   
  17.   public constructor(props: IReactSpfxWebPartProps, state: IReactSpfxState){    
  18.     super(props);   
  19.       
  20.     this.state = {    
  21.       items: [    
  22.         {    
  23.           "Courses""",   
  24.           "Credit""",   
  25.           "Department":"",  
  26.            
  27.         }    
  28.       ]    
  29.     };    
  30.   }    
  31.     
  32. private componentDidMount() {  
  33.      setInterval(  
  34.       () => this.fetchDatafromSharePointList(),  
  35.       1000  
  36.     );  
  37.   }  
  38.   
  39. private fetchDatafromSharePointList()  
  40. {  
  41.   var reactHandler = this;    
  42.     jquery.ajax({    
  43.         url: `${this.props.siteurl}/_api/web/lists/getbytitle('CourseDetails')/items`,    
  44.         type: "GET",    
  45.         headers:{'Accept''application/json; odata=verbose;'},    
  46.         success: function(resultData) {    
  47.           /*resultData.d.results;*/    
  48.           reactHandler.setState({    
  49.             items: resultData.d.results    
  50.           });    
  51.         },    
  52.         error : function(jqXHR, textStatus, errorThrown) {    
  53.         }    
  54.     });    
  55. }  
  56.   
  57.   public render(): React.ReactElement<IReactSpfxWebPartProps> {  
  58.       
  59.      return (    
  60.       <div className={styles.panelStyle} >   
  61.           
  62.           <div className={styles.tableCaptionStyle} >Fetch   
  63.           Course Details from SharePointList using SPFx,RESTAPI,React JS  
  64.             Data on page changes with change in the SharePointList  </div>  
  65.            
  66.            <div className={styles.headerCaptionStyle} >Course Details</div>  
  67.           <div className={styles.tableStyle} >     
  68.               
  69.             <div className={styles.headerStyle} >    
  70.               <div className={styles.CellStyle}>Courses</div>    
  71.               <div className={styles.CellStyle}>Credit </div>    
  72.               <div className={styles.CellStyle}>Department</div>    
  73.                   
  74.                        
  75.             </div>    
  76.               
  77.               {this.state.items.map(function(item,key){    
  78.                   
  79.                 return (<div className={styles.rowStyle} key={key}>    
  80.                     <div className={styles.CellStyle}>{item.Courses}</div>    
  81.                     <div className={styles.CellStyle}>{item.Credit}</div>    
  82.                      <div className={styles.CellStyle}>{item.Department}</div>  
  83.                         
  84.             
  85.                   </div>);    
  86.               })}    
  87.                       
  88.           </div>    
  89.         </div>    
  90.   
  91.   
  92.     );    
  93.   }    
  94.     
  95. }  
ReactSpfxWebPartWebPart.ts
 
This is the main file created by SPFx. This interacts with React files under the Component Folder. Eventually, the rendering happens here.
  1. import * as React from 'react';  
  2. import * as ReactDom from 'react-dom';  
  3. import { Version } from '@microsoft/sp-core-library';  
  4. import {  
  5.   BaseClientSideWebPart,  
  6.   IPropertyPaneConfiguration,  
  7.   PropertyPaneTextField  
  8. } from '@microsoft/sp-webpart-base';  
  9.   
  10. import * as strings from 'reactSpfxWebPartStrings';  
  11. import ReactSpfxWebPart from './components/ReactSpfxWebPart';  
  12. import { IReactSpfxWebPartProps } from './components/IReactSpfxWebPartProps';  
  13. import { IReactSpfxWebPartWebPartProps } from './IReactSpfxWebPartWebPartProps';  
  14.   
  15. export default class ReactSpfxWebPartWebPart extends BaseClientSideWebPart<IReactSpfxWebPartWebPartProps> {  
  16.   
  17.   public render(): void {  
  18.     const element: React.ReactElement<IReactSpfxWebPartProps > = React.createElement(  
  19.       ReactSpfxWebPart,  
  20.       {  
  21.         description: this.properties.description,    
  22.         siteurl: this.context.pageContext.web.absoluteUrl  
  23.       }  
  24.     );  
  25.   
  26.     ReactDom.render(element, this.domElement);  
  27.   }  
  28.   
  29.   protected get dataVersion(): Version {  
  30.     return Version.parse('1.0');  
  31.   }  
  32.   
  33.   protected getPropertyPaneConfiguration(): IPropertyPaneConfiguration {  
  34.     return {  
  35.       pages: [  
  36.         {  
  37.           header: {  
  38.             description: strings.PropertyPaneDescription  
  39.           },  
  40.           groups: [  
  41.             {  
  42.               groupName: strings.BasicGroupName,  
  43.               groupFields: [  
  44.                 PropertyPaneTextField('description', {  
  45.                   label: strings.DescriptionFieldLabel  
  46.                 })  
  47.               ]  
  48.             }  
  49.           ]  
  50.         }  
  51.       ]  
  52.     };  
  53.   }  
  54. }  
IReactSpfxWebPartWebPartProps.ts
 
Interface for WebPart Properties.
  1. export interface IReactSpfxWebPartWebPartProps {  
  2.   description: string;  
  3. }  
Configurations
 
copy-assets.json 
Folder location to be copied to SharePoint Assets library.
  1. {  
  2.   "deployCdnPath""temp/deploy"  
  3. }  
write-manifests.json 
All the files created under temp/deploy should be copied here in order for React webpart to work.
  1. {  
  2.   "cdnBasePath""https://yourtenant/sites/intranet/Site%20Assets"  
  3. }  
package-solution.json 
Most of the fields are relevant. Most important one is zippedpackage. This is the location where the package is created.
  1. {  
  2.   "solution": {  
  3.     "name""react-spfx-web-part-client-side-solution",  
  4.     "id""7d2fa690-094d-4445-b012-97d462b335ae",  
  5.     "version""1.0.0.0",  
  6.     "skipFeatureDeployment"true  
  7.   },  
  8.   "paths": {  
  9.     "zippedPackage""solution/react-spfx-web-part.sppkg"  
  10.   }  
  11. }  
ReactSpfxWebPartWebPart.manifest.json
  1. {  
  2.   "$schema""../../../node_modules/@microsoft/sp-module-interfaces/lib/manifestSchemas/jsonSchemas/clientSideComponentManifestSchema.json",  
  3.   
  4.   "id""3a5f40ec-b0c9-4a4f-acc1-24be14e318f2",  
  5.   "alias""ReactSpfxWebPartWebPart",  
  6.   "componentType""WebPart",  
  7.   
  8.   // The "*" signifies that the version should be taken from the package.json  
  9.   "version""*",  
  10.   "manifestVersion": 2,  
  11.   
  12.   // If true, the component can only be installed on sites where Custom Script is allowed.  
  13.   // Components that allow authors to embed arbitrary script code should set this to true.  
  14.   // https://support.office.com/en-us/article/Turn-scripting-capabilities-on-or-off-1f2c515f-5d7e-448a-9fd7-835da935584f  
  15.   "requiresCustomScript"false,  
  16.   
  17.   "preconfiguredEntries": [{  
  18.     "groupId""3a5f40ec-b0c9-4a4f-acc1-24be14e318f2",  
  19.     "group": { "default""Under Development" },  
  20.     "title": { "default""ReactSpfxWebPart" },  
  21.     "description": { "default": "Retrieving list   
  22.     items and auto refresh on change of data on SharePoint List" },  
  23.     "officeFabricIconFontName""Page",  
  24.     "properties": {  
  25.       "description""ReactSpfxWebPart"  
  26.     }  
  27.   }]  
  28. }  
Build your Project
 
I will use gulp for building the project. Run the below commands to start building the project. Once the project gets built successfully, you will see some files under the temp/deploy folder. These are the files which contain bundled JavaScript and metadata files and are necessary for the webpart to work on SharePoint.
 
This creates files under temp/deploy – which need to be copied to the Assets folder of your site.
  1. gulp build  
  2. gulp -ship  
Running the below commands creates sppkg in your target path.
  1. gulp bundle --ship  
  2. gulp package-solution --ship  
Folder Structure
 
The below screenshot gives an idea to find the necessary files for deployment to SharePoint.
 
SharePoint Framework aka SPFx Web Part Using React And REST API 
 
SharePoint & Local Workbench
 
Type the below command in command prompt. This command starts gulp and opens up a local workbench in the browser.
  1. gulp serve  
This helps to test the web part before deploying the package to SharePoint. Web part can be tested on local as well as SharePoint workbench.

Local WorkBench
 
Testing on local workbench will only retrieve data if mock data has been created.
 
SharePoint Framework aka SPFx Web Part Using React And REST API 
 
Deploy
 
It's time to deploy the package file to SharePoint App Catalog site.
 
SharePoint Framework aka SPFx Web Part Using React And REST API
 
WebPart Deployed on SharePoint
 
Once the webpart is added to AppCatalog, it should be available to add on SharePoint Developer or any other site collection.
 
SharePoint Framework aka SPFx Web Part Using React And REST API 
References
  • https://dev.office.com/sharepoint/docs/spfx/sharepoint-framework-overview  
  • http://yeoman.io  
  • https://facebook.github.io/react  
  • https://gulpjs.com