Amazing Guide To SharePoint Framework Development With React

What do you think when you see the ongoing modern updates in SharePoint Online? Super cool, isn’t it? Modern UI, Modern Pages, Modern web parts and a lot of modern APIs are revolving around SharePoint nowadays. That brings a lot of features to the SharePoint world. The features, which we missed in past days, are coming in the form of new ones.

Developing applications or customizations against SharePoint has improved a lot when compared with a decade-old version of SharePoint. Today, most of the development firms are using client-side technologies to support all modern mobile devices and modern browsers at the same time. To support modern browsers, SharePoint also changed their style and development strategy.

Now, we have a SharePoint framework, a new development model which supports all modern CSS and JavaScript frameworks. This advancement enables the developer to do customizations among Modern UI and pages in the form of web parts and Extensions.

SharePoint team is projecting the new SharePoint Framework as a replacement for the old development models to customize the SharePoint platform based on the business needs. By using this model, we can use any JavaScript framework to develop the web parts against SharePoint. ReactJS is also among them and Microsoft has also created many components using React.js and Office UI fabric. And they are implementing their components in SharePoint Online for modern page development.

So, we too use the same components for SharePoint Framework development from start to end. To prepare the environment, check the below links.

By considering that you have the environment setup ready for developing the SharePoint Framework components, we will start the SharePoint Framework web part by using ReactJS step by step guide.

To create a new SharePoint Framework web part, run the below Yeoman command to scaffold the SharePoint Framework project.

Yo @microsoft/sharepoint

The command asks us the initial project information, before generating the project structure.

  • What is your solution name?   managelists
  • Which baseline packages do you want to target for your component(s)? SharePoint Online only (latest)
  • Where do you want to place the files? Use the current folder
  • Do you want to allow the tenant admin the choice of being able to deploy the solution to all sites immediately without running any feature deployment of adding apps in sites? N
  • Which type of client-side component to create? WebPart
  • What is your web part name? ManageLists
  • What is your web part description? ManageLists description
  • Which framework would you like to use? React

The screenshot for the above selection is shown below.

SharePoint

After selecting React, the generator generates the project structure and downloads the required npm packages for the project. Then it adds them under node_modules folder. The project structure looks like this.

SharePoint

From the Project folder, under src -> web parts -> ManageLists, we will have a required file for the web part development. WebParts folder contains two folders (manageLists & loc) and two files (ManageListWebPart.manifest.json & ManageListsWebPart.ts). The below table gives you an idea of the files and folder.

File / FolderRemarks
ManageListsWebPart.tsInherits from BaseClientSideWebaprt and this is the entry file for the web part
ManageListsWebPart.manifest.jsonConfigure the predefined properties
ComponentsFolder contains the React Component files. Each component contains the control or element generation, style and property files
LocContains the files to support multi-language

Before starting the development, we have to categorize the project structure based on the components and objects for easy understanding and smart development. Below are the categorizations for the React SharePoint Framework.

  • Web part File and Properties
    WebPart file imports from BasicClientsideWebpart. By default, we have this file

  • Object
    Object – Object Declaration

  • React Components
    Each React Component play as a user control and this should be embedded in the web part file. By default, we have this file

  • Data Providers
    Play as the service and which serves the data to the component

From the generator, we have a Components folder and Web part files. We have to manually create the two folders - data provider and common folder object declaration with utility functions.

Under the src -> web parts -> ManageLists folder create Common and DataProviders folder. After creating the folders, project structure looks like below,

SharePoint

Objects and Mock-up Data

Define Object

The project structure is ready now and we have to prepare the interface the object declaration. In our web part, we are about to retrieve the List title and Id from the web. For that create the object interface by creating new file “IObjects.ts” under the common folder. Add the below snippet in newly created file,

  1. export interface IList{  
  2. Title?: string;  
  3. Id?: string;  
  4. }  

Use export keyword to enable this interface to be used from other files across the project. We have to use import keyword from other files for including this reference. Create an interface for providing data connections between object and web part. Create IDataProvider.ts file under data provider folder and add the below code snippet.

  1. import { IList } from './../common/IObjects';  
  2. export interface IDataProvider {  
  3.     getAllLists(): Promise<IList[]>;  
  4. }  

IDataProvider interface used to play as a service to retrieve the values and used by the UI to render within a place.  So, define a method called getAllList() to return an array of IList objects. Add a reference to IList by calling import keyword on top of all.

Initiate Mock-up Data

So far, we have the defined the List object and method in the interface. Now we have to call the method to retrieve the values and fill it in IList array. Create a new file “MockupDataProvider.ts” under DataProvider folder and the below snippet.

  1. import { IList } from './../common/IObjects';  
  2. import { IDataProvider } from './IDataProvider';  
  3.   
  4. export default class MockupDataProvider implements IDataProvider {  
  5.     constructor() {  
  6.     }  
  7.   
  8.     public getAllLists(): Promise<IList[]> {  
  9.         let _items: IList[];  
  10.         //Initiate mockup values to the IList[] object  
  11.         _items = [  
  12.             {  
  13.                 Title: 'List Name 1',  
  14.                 Id: '1'  
  15.             },  
  16.             {  
  17.                 Title: 'List Name 2',  
  18.                 Id: '2'  
  19.             },  
  20.             {  
  21.                 Title: 'List Name 3',  
  22.                 Id: '3'  
  23.             },  
  24.             {  
  25.                 Title: 'List Name 4',  
  26.                 Id: '4'  
  27.             },  
  28.             {  
  29.                 Title: 'List Name 5',  
  30.                 Id: '5'  
  31.             }  
  32.         ];  
  33.   
  34.         //Returns the mockup data   
  35.         return new Promise<IList[]>((resolve) => {  
  36.             setTimeout(() => {  
  37.                 resolve(_items);  
  38.             }, 2000);  
  39.         });  
  40.     }  
  41. }  

MockupDataProvider class inherits from IDataProvider to use its defined method. Within getAllLists declare the IList array type variable and assign the values to that. Returning those items _items as array of IList object in asynchronous way using promise.

Render mock-up Data in SharePoint Framework web part:   SPFx WebPart Render Method

Navigate to the web parts -> manageLists folder and open ManageWebPartList.ts

Add  MockupDataProvider reference to the file by adding the below line

import   MockupDataProvider  from './dataproviders/MockupDataProvider';

Within render() method, remove the description property. Then add the provider property by defining MockupProvider as a data type.

description: this.properties.description
provider:new MockupProvider()

By using the provider property we are initializing MockUpDataProvider object and passing this object to the ReactComponent. The React Component take care of retrieving the mockup values and generating the HTML.

The code snippet under render() method looks like bellows,

  1. public render(): void {  
  2.     const element: React.ReactElement<IManageListsProps > = React.createElement(  
  3.       ManageLists,  
  4.       {  
  5.         provider: new MockupDataProvider()  
  6.       }  
  7.     );  
  8.     ReactDom.render(element, this.domElement);  
  9.   }  

So far, we have defined the properties, methods and passing the parameter from web part to react component.

React Component State

React Component is an independent, reusable control/component contains HTML and Javascript. React component has render method, which will be called and render the HTML during the component initialization. The data for react component data will be stored in component’s state.  This state can be updated based on the user’s action. Whenever the component’s state changes, React will re-render the component in the Brower.

We have to implement Component state to define the data property IList. So navigate to src -> webparts -> manageLists -> components folder and create a new file called IManageListsState.ts

Add the below code snippet in IManageListsState.ts file,

  1. import { IList } from './../common/IObjects';  
  2. interface IManageListsState{  
  3.     lists: IList[];  
  4. }  
  5. export default IManageListsState;  
React Component Properties

Component Properties also is very important, because we are passing the parameter from Web part to react component via component properties. And this is similar to arguments for pure functions. In our example, we are passing provider parameter from web part to react component. We have a separate file for having component properties.

Navigate to the components folder and open IManageListsProps.ts file.

Add the reference to the IDataProvider by adding

  1. import { IDataProvider } from './../dataproviders/IDataProvider';  

Remove the existing properties and then add the property “provider” as a data type IDataProvider.

Now the IManageListsProbs.ts looks like below,

  1. import { IDataProvider } from './../dataproviders/IDataProvider';  
  2. export interface IManageListsProps {  
  3.   provider:IDataProvider;    
  4. }  

By using IManageListProps, we are defining the properties for React Component. We should add the “provider” attribute with value to the React Component in web part file. The code from React component uses the value passed from web part.

React Component and HTML Generation

We have Component Properties, State, Mock-up data, provider for sending data to component and web part for rendering the component. Now we have to develop the component to link all objects to render it in a browser.

By default, React Component file is available during the creating from project using Yeoman generator. To open the component file, navigate to src -> webparts -> manageLists -> components and then click ManageLists.tsx

Import the object, state and provider references to the component by adding below snippet before the class,

  1. import IManageListsState from './IManageListsState';  
  2. import { IDataProvider } from './../dataproviders/IDataProvider';  
  3. import { IList } from './../common/IObjects';  

Then, we have to add the state parameter to the component ManageLists class by replacing {} with IManageListsState.

  1. export default class ManageLists extends React.Component<IManageListsProps, {}> {  

Replacing the above line with the below snippet

  1. export default class ManageLists extends React.Component<IManageListsProps, IManageListsState> {  

Add the constructor to initialize the variables for the component. First, we will initialize the state by adding the below constructor code within the class.

  1. constructor(props: IManageListsProps) {  
  2.     super(props);  
  3.     this.state = {  
  4.       lists: []  
  5.     };  
  6.   }  

Remove the render method from manageLists class and add the below code to send the generated HTML to the webpart to render in browser.

  1. public render(): React.ReactElement<IManageListsProps> {      
  2.     return (  
  3.       <div className={styles.manageLists}>  
  4.         <div className={styles.container}>  
  5.           <div className={styles.row}>  
  6.             <div className={styles.column}>  
  7.               <span className={styles.title}>Total Lists: {escape(this.state.lists.length.toString())}</span>  
  8.               { this.state.lists.map(function(item,key){    
  9.                 return(<p key={key} className={styles.description}>{item.Title}</p>);  
  10.               })}                
  11.             </div>  
  12.           </div>  
  13.         </div>  
  14.       </div>  
  15.     );  
  16.   }  

Now, we have generated the HTML in render method to call the provider method for retrieving the data. For that, we will use the React’s componentDidMount method to call the getAllLists() method from the provider property of the component. Then, set the returned IList values to the State object by using the below code.

  1. public componentDidMount() {  
  2.     this.props.provider.getAllLists().then((_lists: IList[]) => {  
  3.       this.setState({  
  4.         lists: _lists  
  5.       });  
  6.     });  
  7.   }  

The combined code for the React component file ManageLists.tsx looks like below.

  1. import * as React from 'react';  
  2. import styles from './ManageLists.module.scss';  
  3. import { IManageListsProps } from './IManageListsProps';  
  4. import { escape } from '@microsoft/sp-lodash-subset';  
  5. import IManageListsState from './IManageListsState';  
  6. import { IDataProvider } from './../dataproviders/IDataProvider';  
  7. import { IList } from './../common/IObjects';  
  8.   
  9. export default class ManageLists extends React.Component<IManageListsProps, IManageListsState> {  
  10.     
  11.   constructor(props: IManageListsProps) {  
  12.     super(props);  
  13.     this.state = {  
  14.       lists: []  
  15.     };  
  16.   }  
  17.   
  18.   public componentDidMount() {  
  19.     this.props.provider.getAllLists().then((_lists: IList[]) => {  
  20.       this.setState({  
  21.         lists: _lists  
  22.       });  
  23.     });  
  24.   }  
  25.   
  26.   public render(): React.ReactElement<IManageListsProps> {      
  27.     return (  
  28.       <div className={styles.manageLists}>  
  29.         <div className={styles.container}>  
  30.           <div className={styles.row}>  
  31.             <div className={styles.column}>  
  32.               <span className={styles.title}>Total Lists: {escape(this.state.lists.length.toString())}</span>  
  33.               { this.state.lists.map(function(item,key){    
  34.               return(<p key={key} className={styles.description}>{item.Title} ({item.Id})</p>);  
  35.               })}                
  36.             </div>  
  37.           </div>  
  38.         </div>  
  39.       </div>  
  40.     );  
  41.   }  
  42. }  

After completing all the above steps, run the gulp serve command. This will open the SharePoint Workbench in the browser. Or navigate to the workbench page -

https://localhost:4321/temp/workbench.html

Output

Then, add the ManageLists web part to the workbench page and the output looks like below.

Output

The output returns the mockup values defined in MockupDataProvider via ReactComponent and Web part.

Conclusion

Here, we have learned how to render the mockup data in SharePoint Framework using ReactJS. Stay tuned for the next article on how to render SharePoint List information in a web part. The source for this framework web part available in GitHub link.