Building a Basic Web Part with PnPjs in SharePoint Framework (SPFx)

In this article, we will build a basic web part in SharePoint Framework (SPFx) using PnPjs to fetch and display items from a SharePoint list. We will walk through the configuration, fetching data, and rendering it in a web part using React. Let’s get started!

1. Setting Up PnPjs Configuration

First, we need to configure PnPjs to interact with SharePoint and Graph API. We’ll do this by creating a pnpjsConfig.ts file that will initialize the SPFx context for our PnPjs requests.

pnpjsConfig.ts

/* eslint-disable no-var */
import { WebPartContext } from "@microsoft/sp-webpart-base";

// import pnp and pnp logging system
import { ISPFXContext, spfi, SPFI, SPFx as spSPFx } from "@pnp/sp";
import { graphfi, GraphFI, SPFx as graphSPFx } from "@pnp/graph";
import "@pnp/sp/webs";
import "@pnp/sp/lists";
import "@pnp/sp/items";
import "@pnp/sp/batching";

var _sp: SPFI;
var _graph: GraphFI;

export const getSP = (context?: WebPartContext): SPFI => {
  if (_sp === undefined || _sp === null) {
    _sp = spfi().using(spSPFx(context as ISPFXContext));
  }
  return _sp;
};

export const getGraph = (context?: WebPartContext): GraphFI => {
  if (_graph === undefined || _graph === null) {
    _graph = graphfi().using(graphSPFx(context as ISPFXContext));
  }
  return _graph;
};

This file sets up the getSP and getGraph functions that we will use to initialize the PnP context for SharePoint and Graph API.

2. Web Part Implementation

Now, we will create the web part that fetches items from a SharePoint list. We’ll use the getSP function to initialize the SharePoint context and fetch the items. Here’s how we can implement this in the web part.

PnPGetItensBasicoConsoleWebPart.ts

import * as React from 'react';
import * as ReactDom from 'react-dom';
import { Version } from '@microsoft/sp-core-library';
import {
  IPropertyPaneConfiguration,
  PropertyPaneTextField
} from '@microsoft/sp-property-pane';
import { BaseClientSideWebPart } from '@microsoft/sp-webpart-base';

import * as strings from 'PnPGetItensBasicoConsoleWebPartStrings';
import PnPGetItensBasicoConsole from './components/PnPGetItensBasicoConsole';
import { IPnPGetItensBasicoConsoleProps } from './components/IPnPGetItensBasicoConsoleProps';
import { getSP } from './pnpjsConfig';

export interface IPnPGetItensBasicoConsoleWebPartProps {
  description: string;
}

export default class PnPGetItensBasicoConsoleWebPart extends BaseClientSideWebPart<IPnPGetItensBasicoConsoleWebPartProps> {

  public sp: any;
  public items: any[];

  public render(): void {
    this.getListItems().then(() => {
      const element: React.ReactElement<IPnPGetItensBasicoConsoleProps> = React.createElement(
        PnPGetItensBasicoConsole,
        {
          items: this.items
        }
      );
      ReactDom.render(element, this.domElement);
    });
  }

  protected async onInit(): Promise<void> {
    this.sp = getSP(this.context);
  }

  private async getListItems() {
    this.items = await this.sp.web.lists.getByTitle("ListaExemplo").items();
  }

  protected onDispose(): void {
    ReactDom.unmountComponentAtNode(this.domElement);
  }

  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
                })
              ]
            }
          ]
        }
      ]
    };
  }
}

Explanation:

  • onInit: Initializes the PnP SP context using getSP.
  • getListItems: Fetches the items from a list named “ListaExemplo”.
  • render: After fetching the items, it renders them using a React component (PnPGetItensBasicoConsole).

3. React Component to Display Items

We will now create the React component that receives the items as a prop and displays them.

PnPGetItensBasicoConsole.tsx

import * as React from 'react';
import { IPnPGetItensBasicoConsoleProps } from './IPnPGetItensBasicoConsoleProps';

export default class PnPGetItensBasicoConsole extends React.Component<IPnPGetItensBasicoConsoleProps, {}> {

  public render(): React.ReactElement<IPnPGetItensBasicoConsoleProps> {
    const { items } = this.props;

    return (
      <div>
        <h2>List Items</h2>
        {items && items.length > 0 ? (
          <ul>
            {items.map(item => (
              <li key={item.Id}>{item.Title}</li>
            ))}
          </ul>
        ) : (
          <p>No items found</p>
        )}
      </div>
    );
  }
}

Explanation:

  • This component expects items as a prop and renders the list items inside an unordered list (<ul>).
  • If there are no items, it shows a fallback message saying "No items found".

4. Defining the Props Interface

To ensure type safety, we need to define the interface for the items we are working with. Let’s define an interface for the list items.

IPnPGetItensBasicoConsoleProps.ts

export interface IListItem {
  Id: number;
  Title: string;
}

export interface IPnPGetItensBasicoConsoleProps {
  items: IListItem[];
}

Explanation:

  • IListItem defines the structure of each item in the list with Id and Title.
  • IPnPGetItensBasicoConsoleProps defines the structure of the props passed to the PnPGetItensBasicoConsole component.

Conclusion

In this article, we successfully built a basic SPFx web part using PnPjs to fetch items from a SharePoint list and display them using React. The approach used here allows for modular configuration and type safety by utilizing TypeScript and the PnPjs library effectively.

Edvaldo Guimrães Filho Avatar

Published by

Categories:

Leave a comment