PnP JavaScript Library With ReactJS In SharePoint

In my previous posts, I had given gave an intro to PnP JS Core library and the basic code snippets to access SharePoint objects, using PnP-JS-Core component,the reference to which is given below:

The details mentioned at the links given above provide some basic idea about PnP-JS-Core library and how to use the library in accessing SharePoint.

Previously, I used PnP-JS-Core library to integrate with Angular JS to show the available sub sites from the parent site.

In this article, I’m going to simulate the same result by using React JS framework to display the sub sites with the basic details in a table format.

What are the files required?

  • React.js A JavaScript library for building user interfaces.
  • React-dom.js React package for working with DOM.
  • Browser.js Enables you to compile the JavaScript with xml format with in text/babel to JavaScript.
  • Pnp.js PnP JavaScript library.
  • Fetch.js Used by PnP js file to handle web requests and responses (Required for IE).
  • Promise.js Used by PnP js file to handle the Web requests and the responses (Required for IE).

    Note: Fetch JS & Promise JS files, required to run PnP methods in some Browsers (IE).

Include Script Files

I have uploaded the required script file under Site Assets library and added the lines, given below, to our sample HTML file.

  1. <script type="text/javascript" src="/siteassets/scripts/pnp.min.js"></script>   
  2. <script type="text/javascript" src="/siteassets/scripts/fetch.js"></script>   
  3. <script type="text/javascript" src="/siteassets/scripts/promise.min.js"></script>   
  4. <script type="text/javascript" src="/siteassets/scripts/react.js"></script>  
  5. <script type="text/javascript" src="/siteassets/scripts/react-dom.js"></script>  
  6. <script type="text/javascript" src="/siteassets/scripts/browser.min.js"></script>  
Include HTML

Add the css styles given below to the sample HTML file. The Id with tableContainer is replaced with the sub sites table.
  1. <!-- To style table in html -->  
  2. <style type="text/css">   
  3. .web-table th{ background-color:#ddd; border:2px solid #fff;}   
  4. .web-table td{ background-color:#eee; border:2px solid #fff;}   
  5. .web-heading{ padding:2px;}   
  6. </style>  
  7. <div id='tableContainer'></div>  
  8. <script type=’text/babel’>  
  9.     <!- - Insert React JSX Code - -></script>  
Include React JSX

To create a table with sub site details in the rows, we have to create a separate React element for each component:
  • Row
  • Table
  • Container
  • Render

    Note: Including browser.js file is used to compile react jsx lines to JavaScript

Row component in React JSX

  1. //Create Row component  
  2. var ResultItem = React.createClass({  
  3. render: function(){  
  4. return (  
  5.   
  6. <tr>  
  7.     <td>{this.props.webTitle} </td>  
  8.     <td>{this.props.webId} </td>  
  9.     <td>{this.props.webCreated.toLocaleString()}</td>  
  10.     <td>{this.props.webTemplate}</td>  
  11. </tr>  
  12. );  
  13. }  
  14. });  
In the table for each row, add the <ResultItem> with the property attributes in the table component. Render method is used to display Web title, Id, created date and template Id as an output.

Table component in React JSX
  1. //Create Table component - Within a table component, we have declared the headings for the table  
  2. var Results = React.createClass({  
  3.     render: function() {  
  4.         var resultItems = this.props.pnpResponse.map(function(result) {  
  5.             return <ResultItem webId = {  
  6.                 result.Id  
  7.             }  
  8.             webTitle = {  
  9.                 result.Title  
  10.             }  
  11.             webTemplate = {  
  12.                 result.WebTemplate  
  13.             }  
  14.             webCreated = {  
  15.                 new Date(result.Created)  
  16.             }  
  17.             />  
  18.         });  
  19.         return ( < table width = "100%"  
  20.             cellPadding = "10"  
  21.             cellSpacing = "2"  
  22.             className = "web-table" > < thead > < tr > < th > Title < /th>  < th > Id < /th>  < th > Created < /th>  < th > Web Template < /th>  < /tr>  < /thead> < tbody > {  
  23.                 resultItems  
  24.             } < /tbody> < /table>);  
  25.     }  
  26. });  
In the table component a <Result>element returns the table with the header & the body. {resultItems} are used to render the <ResultItem> element, that renders each row, based on the initialized property.

Container component in React JSX
  1. //ShowWebsApp is the parent component, which renders the table and each row component.  
  2. var ShowWebsApp = React.createClass({  
  3.     getInitialState: function() {  
  4.         return {  
  5.             pnpResults: []  
  6.         }  
  7.     },  
  8.     componentDidMount: function() {  
  9.         this.getWebs();  
  10.     },  
  11.     showResults: function(response) {  
  12.         this.setState({  
  13.             pnpResults: response  
  14.         })  
  15.     },  
  16.     getWebs: function() {  
  17.         $pnp.sp.web.webs.get().then(function(result) {  
  18.             this.showResults(result);  
  19.         }.bind(this));  
  20.     },  
  21.     render: function() {  
  22.         return ( < div > < Results pnpResponse = {  
  23.                 this.state.pnpResults  
  24.             }  
  25.             /> < /div>);  
  26.     }  
  27. });  
<Results> element is the container component and in our example, this is the main component used to interact with PnP-JS-Core library to get the array of the sub-sites. Within this class, object getInitialState, componentDidMount, render methods are React functions. 
  • getInitialState initializes the array object (pnpResults) to store the Web information.
  • componentDidMount method is invoked only once and calls the custom method getWebs(), immediately after the rendering occurs .
  • getWebs method is used in PnP JavaScript method to get the subsite values and store the result to pnpResults array object.
  • Render method sets the pnpResults (array of subsites) object to the pnpResponse attribute by using setState react function.

Note: In the table component array of pnpResponse, value maps the value to each row by calling the map function.

Render component in ReactJSX

//Render the container component in HTML element with Id “tableContainer”

ReactDOM.render(<ShowWebsApp/>, document.getElementById('tableContainer'));

Full Sample Code

Insert the code, given below, in Script Editor or Content Editor Web-part.

  1. <script type="text/javascript" src="/siteassets/scripts/pnp.min.js"></script>  
  2. <script type="text/javascript" src="/siteassets/scripts/fetch.js"></script>  
  3. <script type="text/javascript" src="/siteassets/scripts/promise.min.js"></script>  
  4. <script type="text/javascript" src="/siteassets/scripts/react.js"></script>  
  5. <script type="text/javascript" src="/siteassets/scripts/react-dom.js"></script>  
  6. <script type="text/javascript" src="/siteassets/scripts/browser.min.js"></script>  
  7. <!-- To style table in html -->  
  8. <style type="text/css">  
  9.     .web-table th {  
  10.         background-color: #ddd;  
  11.         border: 2px solid #fff;  
  12.     }  
  13.       
  14.     .web-table td {  
  15.         background-color: #eee;  
  16.         border: 2px solid #fff;  
  17.     }  
  18.       
  19.     .web-heading {  
  20.         padding: 2px;  
  21.     }  
  22. </style>  
  23. <div id='tableContainer'></div>  
  24. <!-- browser.min.js file used to compile and transfer the scripts within text/babel script element to javascript readle for React javascript library -->  
  25. <script type="text/babel"> //ShowWebsApp is the parent component, which renders the table and each row component. var ShowWebsApp = React.createClass({ getInitialState: function(){ return{ pnpResults: [] } }, componentDidMount: function() { this.getWebs(); }, showResults: function(response){ this.setState({ pnpResults: response }) }, getWebs: function(){ $pnp.sp.web.webs.get().then(function(result) { this.showResults(result); }.bind(this)); }, render: function(){ return (  
  26.     <div>  
  27.         <Results pnpResponse={this.state.pnpResults} /> </div> ); } }); //Create Table component - Within a table component, we have declared the headings for the table var Results = React.createClass({ render: function(){ var resultItems = this.props.pnpResponse.map(function(result){ return  
  28.     <ResultItem webId={result.Id} webTitle={result.Title} webTemplate={result.WebTemplate} webCreated={new Date(result.Created)} /> }); return(  
  29.     <table width="100%" cellPadding="10" cellSpacing="2" className="web-table">  
  30.         <thead>  
  31.             <tr>  
  32.                 <th>Title</th>  
  33.                 <th>Id</th>  
  34.                 <th>Created</th>  
  35.                 <th>Web Template</th>  
  36.             </tr>  
  37.         </thead>  
  38.         <tbody> {resultItems} </tbody>  
  39.     </table> ); } }); //Create Row component var ResultItem = React.createClass({ render: function(){ return (  
  40.     <tr>  
  41.         <td>{this.props.webTitle} </td>  
  42.         <td>{this.props.webId} </td>  
  43.         <td>{this.props.webCreated.toLocaleString()}</td>  
  44.         <td>{this.props.webTemplate}</td>  
  45.     </tr> ); } }); //Render the container component in html element with id “tableContainer” ReactDOM.render(  
  46.     <ShowWebsApp/>, document.getElementById('tableContainer')); </script>  
Output

Output

Conclusion

This article provides a simple example to list the sub sites in a table format, using React JS framework.

Click here to read this article from my blog too.