SharePoint Framework CRUD Operations using React

If you want to learn SharePoint Framework development, the first thing you should try is SharePoint framework crud operations using react. So let us check step by step SPFx CRUD Operations using React in SharePoint Online.

Here we will create an SPFx client side web part using the React framework and will do the CRUD operations example like how to display items from a SharePoint Online list using SPFx React, insert items to SharePoint Online list using SPFx react, how to update delete items from SharePoint list using SPFx react and how to delete an item from SharePoint Online list using SharePoint Framework (SPFx) using react js.

Here we will discuss:

  • SharePoint framework crud operations using react
  • spfx crud operations using react pnp
  • spfx crud operations using react – display items from SharePoint Online list
  • sharepoint framework crud operations – Insert items to SharePoint Online list
  • sharepoint framework crud operations – Update an item from a SharePoint Online list
  • spfx crud operations using react pnp – Delete an item from a SharePoint Online list

Here, we will see how build something like below:

spfx crud operations using react
spfx crud operations using react

SharePoint framework crud operations using react

Now let us see step by step how to develop SharePoint framework crud operations using react.

By this time, I suppose you have already done the development environment set up for SPFx. I have also created a video tutorial on how to setup a development environment for SharePoint Framework development.

For this SharePoint framework crud operations using react example, I have taken a SharePoint Online list like below:

  • Employee Name (People Picker)
  • HireDate (DateTime)
  • Job Description (Multiline text)

The SharePoint Online list looks like below:

sharepoint framework react webpart crud operations
sharepoint framework react webpart crud operations

SPFx crud operations using react – Create the SPFx solution

Now, let us see how to create the SPFx solution for a CRUD operation using React.

Open Node.js command prompt in administrator mode. You can also use windows command prompt, PowerShell command prompts. The run the below command:

md CURDReact1

cd CURDReact1

Then in the same directory run the below command:

yo @microsoft/sharepoint

Now, it will ask you a few details like below:

  • What is your solution name? Click enter to take the default value.
  • Which baseline packages do you want to target for your component(s). You can choose from the below options
    • SharePoint Online Only (latest)
    • SharePoint 2016 onwards, including 2019 and SharePoint Online
    • SharePoint 2019 onwards, including SharePoint Online
  • Press Enter to choose the default one (SharePoint Online Only (latest).
  • Where do you want to place the files?
    • Use the current folder
    • Create a subfolder with solution name, press enter to use the first option.
  • 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 or adding apps in sites? Type N.
  • Will the components in the solution require permissions to access web APIs that are unique and not shared with other components in the tenant. Type N.
  • Which type of client-side component to create?
    • WebPart
    • Extension
    • Library
  • Here choose WebPart.

Next, it will ask you about the web part details.

  • What is your web part name? HelloWorld Click Enter
  • What is your Web part description? HelloWorld description Click Enter
  • Which framework would you like to use? Select React from the below options:
    • No JavaScript framework
    • React
    • Knockout
spfx crud operations using react
spfx crud operations using react

Then it will take sometime and create the solution, you can see the successful message like below:

spfx crud operations using react pnp
spfx crud operations using react pnp

SPFx crud operations using react – Install PnP/SP and PnP SPFx Controls

In this sharepoint framework crud operations example, we are going to use the PnP js and PnP SPFx react controls here. So once the SPFx solution got created, run the below commands to install pnp js and pnp spfx react controls, so that we can use them in the SPFx project and solution.

npm i @pnp/sp

npm i @pnp/spfx-controls-react

You can also install both the command at once.

npm i @pnp/sp @pnp/spfx-controls-react
sharepoint framework crud operations using react pnp
sharepoint framework crud operations using react pnp

Once the installation is successful, run the below command to open the solution using visual studio code.

code .

You can also check how to use PnP react people picker control.

SharePoint framework crud operations – Display SharePoint Online List Items

When you will open the SPFx web part, it will display all the SharePoint Online list items.

Either you can write the code in the default .tsx file or you can create your own .tsx file. Here, I have created a new .tsx file and we are going to write all the code in this file.

To create a new tsx file, right-click on the components folder, then add a new file and then give the <filename.tsx>.

sharepoint framework crud operations
sharepoint framework crud operations

Here, we need to have the context, and web URL so first open the IHelloWorldProps.ts file and modify like below:

import { WebPartContext } from "@microsoft/sp-webpart-base";

export interface IHelloWorldProps {
  description: string;
  context: WebPartContext;
  webURL:string;
}

Then open the HelloWorldWebPart.ts file and modify the render method like below:

public render(): void {
    const element: React.ReactElement<IHelloWorldProps> = React.createElement(
      CRUDReact,
      {
        description: this.properties.description,
        webURL:this.context.pageContext.web.absoluteUrl,
        context:this.context
      }
    );

    ReactDom.render(element, this.domElement);
  }

Also, write the import statement like below:

import CRUDReact from './components/CRUDReact';

Next, open the react component file and we need to add all our code here.

First write the below import statements.

import * as React from 'react';
import styles from './HelloWorld.module.scss';
import { IHelloWorldProps } from './IHelloWorldProps';
import { escape } from '@microsoft/sp-lodash-subset';
import { DatePicker, IDatePickerStrings } from 'office-ui-fabric-react/lib/DatePicker';
import { PeoplePicker, PrincipalType } from "@pnp/spfx-controls-react/lib/PeoplePicker";
import { TextField } from 'office-ui-fabric-react/lib/TextField';
import { Label } from 'office-ui-fabric-react/lib/Label';
import { sp, Web, IWeb } from "@pnp/sp/presets/all";
import "@pnp/sp/lists";
import "@pnp/sp/items";
import { PrimaryButton } from 'office-ui-fabric-react/lib/Button';

Here, we are going to use a few Office ui fabric react controls and also we are going to use the PnP react controls for People picker.

Then write the below code to render the form using react controls.

public render(): React.ReactElement<IHelloWorldProps> {
        return (
          <div>
            <h1>CRUD Operations With ReactJs</h1>
            {this.state.HTML}
            <div className={styles.btngroup}>
              <div><PrimaryButton text="Create" onClick={() => this.SaveData()}/></div>
              <div><PrimaryButton text="Update" onClick={() => this.UpdateData()} /></div>
              <div><PrimaryButton text="Delete" onClick={() => this.DeleteData()}/></div>
            </div>
            <div>
              <form>
                <div>
                  <Label>Employee Name</Label>
                  <PeoplePicker
                    context={this.props.context}
                    personSelectionLimit={1}
                    // defaultSelectedUsers={this.state.EmployeeName===""?[]:this.state.EmployeeName}
                    required={false}
                    onChange={this._getPeoplePickerItems}
                    defaultSelectedUsers={[this.state.EmployeeName?this.state.EmployeeName:""]}
                    showHiddenInUI={false}
                    principalTypes={[PrincipalType.User]}
                    resolveDelay={1000}
                    ensureUser={true}
                  />
                </div>
                <div>
                  <Label>Hire Date</Label>
                  <DatePicker maxDate={new Date()} allowTextInput={false} strings={DatePickerStrings} value={this.state.HireDate} onSelectDate={(e) => { this.setState({ HireDate: e }); }} ariaLabel="Select a date" formatDate={FormatDate} />
                </div>
                <div>
                  <Label>Job Description</Label>
                  <TextField value={this.state.JobDescription} multiline onChanged={(value) => this.onchange(value, "JobDescription")} />
                </div>
    
              </form>
            </div>
          </div>
        );
      }

Then declare the interface like below:

export interface IStates {
    Items: any;
    ID: any;
    EmployeeName: any;
    EmployeeNameId: any;
    HireDate: any;
    JobDescription: any;
    HTML: any;
  }

In the constructor, set the everything empty,

constructor(props) {
        super(props);
        this.state = {
          Items: [],
          EmployeeName: "",
          EmployeeNameId: 0,
          ID: 0,
          HireDate: null,
          JobDescription: "",
          HTML: []
    
        };
      }

Then in the react componentDidMount() method, write the below code to get the items from the SharePoint Online list.

 public async componentDidMount() {
        await this.fetchData();
      }
    
      public async fetchData() {
       
        let web = Web(this.props.webURL);
        const items: any[] = await web.lists.getByTitle("EmployeeDetails").items.select("*", "Employee_x0020_Name/Title").expand("Employee_x0020_Name/ID").get();
        console.log(items);
        this.setState({ Items: items });
        let html = await this.getHTML(items);
        this.setState({ HTML: html });
      }

public async getHTML(items) {
        var tabledata = <table className={styles.table}>
          <thead>
            <tr>
              <th>Employee Name</th>
              <th>Hire Date</th>
              <th>Job Description</th>
            </tr>
          </thead>
          <tbody>
            {items && items.map((item, i) => {
              return [
                <tr key={i} onClick={()=>this.findData(item.ID)}>
                  <td>{item.Employee_x0020_Name.Title}</td>
                  <td>{FormatDate(item.HireDate)}</td>
                  <td>{item.Job_x0020_Description}</td>
                </tr>
              ];
            })}
          </tbody>
    
        </table>;
        return await tabledata;
      }

export const FormatDate = (date): string => {
    console.log(date);
    var date1 = new Date(date);
    var year = date1.getFullYear();
    var month = (1 + date1.getMonth()).toString();
    month = month.length > 1 ? month : '0' + month;
    var day = date1.getDate().toString();
    day = day.length > 1 ? day : '0' + day;
    return month + '/' + day + '/' + year;
  };

SPFx crud operation using reactjs – Insert item to SharePoint Online list

Now, let us see how to add item to SharePoint Online list in the SharePoint framework CRUD operations using reactjs example.

Here, I have added the item using PnP and once the item got created, we are calling the setState(), so that it will make the form fields empty. And then calling the fetchData() method, so that it will reload the data and we can see the updated items.

private async SaveData() {
        let web = Web(this.props.webURL);
        await web.lists.getByTitle("EmployeeDetails").items.add({
    
          Employee_x0020_NameId:this.state.EmployeeNameId,
          HireDate: new Date(this.state.HireDate),
          Job_x0020_Description: this.state.JobDescription,
    
        }).then(i => {
          console.log(i);
        });
        alert("Created Successfully");
        this.setState({EmployeeName:"",HireDate:null,JobDescription:""});
        this.fetchData();
      }

SharePoint framework crud operations – Update List item using Reactjs

Let us see now, how to do the update operation in the SharePoint framework crud operations example.

It will display the items in the HTML table and once user clicks on an item, the values will be populated.

<tbody>
            {items && items.map((item, i) => {
              return [
                <tr key={i} onClick={()=>this.findData(item.ID)}>
                  <td>{item.Employee_x0020_Name.Title}</td>
                  <td>{FormatDate(item.HireDate)}</td>
                  <td>{item.Job_x0020_Description}</td>
                </tr>
              ];
            })}
          </tbody>


public findData = (id): void => {
        //this.fetchData();
        var itemID = id;
        var allitems = this.state.Items;
        var allitemsLength = allitems.length;
        if (allitemsLength > 0) {
          for (var i = 0; i < allitemsLength; i++) {
            if (itemID == allitems[i].Id) {
              this.setState({
                ID:itemID,
                EmployeeName:allitems[i].Employee_x0020_Name.Title,
                EmployeeNameId:allitems[i].Employee_x0020_NameId,
                HireDate:new Date(allitems[i].HireDate),
                JobDescription:allitems[i].Job_x0020_Description
              });
          }
        }
      }
    
      }

Once the values will be updated in the form, write the below code to submit the item to the SharePoint Online list.

private async UpdateData() {
        let web = Web(this.props.webURL);
        await web.lists.getByTitle("EmployeeDetails").items.getById(this.state.ID).update({
    
          Employee_x0020_NameId:this.state.EmployeeNameId,
          HireDate: new Date(this.state.HireDate),
          Job_x0020_Description: this.state.JobDescription,
    
        }).then(i => {
          console.log(i);
        });
        alert("Updated Successfully");
        this.setState({EmployeeName:"",HireDate:null,JobDescription:""});
        this.fetchData();
      }

SPFx crud operations using react pnp – Delete Item from SharePoint Online

Now, let us see how to delete an item from a SharePoint Online list using SPFx crud operations using react pnp application.

Below is the delete code for SPFx crud operations using react.

private async DeleteData() {
        let web = Web(this.props.webURL);
        await web.lists.getByTitle("EmployeeDetails").items.getById(this.state.ID).delete()
        .then(i => {
          console.log(i);
        });
        alert("Deleted Successfully");
        this.setState({EmployeeName:"",HireDate:null,JobDescription:""});
        this.fetchData();
      }

Once you select an item, and click on the Delete button, the item will be deleted from the SharePoint Online list.

SPFx crud operations using react – Complete Code

Below is the complete code that you can use for CRUD operations using SPFx and react.

Here is the complete code for CRUDReact.tsx

import * as React from 'react';
import styles from './HelloWorld.module.scss';
import { IHelloWorldProps } from './IHelloWorldProps';
import { escape } from '@microsoft/sp-lodash-subset';
import { DatePicker, IDatePickerStrings } from 'office-ui-fabric-react/lib/DatePicker';
import { PeoplePicker, PrincipalType } from "@pnp/spfx-controls-react/lib/PeoplePicker";
import { TextField } from 'office-ui-fabric-react/lib/TextField';
import { Label } from 'office-ui-fabric-react/lib/Label';
import { sp, Web, IWeb } from "@pnp/sp/presets/all";
import "@pnp/sp/lists";
import "@pnp/sp/items";
import { PrimaryButton } from 'office-ui-fabric-react/lib/Button';

export interface IStates {
    Items: any;
    ID: any;
    EmployeeName: any;
    EmployeeNameId: any;
    HireDate: any;
    JobDescription: any;
    HTML: any;
  }

export default class CRUDReact extends React.Component<IHelloWorldProps, IStates> {
    constructor(props) {
        super(props);
        this.state = {
          Items: [],
          EmployeeName: "",
          EmployeeNameId: 0,
          ID: 0,
          HireDate: null,
          JobDescription: "",
          HTML: []
    
        };
      }
    
      public async componentDidMount() {
        await this.fetchData();
      }
    
      public async fetchData() {
       
        let web = Web(this.props.webURL);
        const items: any[] = await web.lists.getByTitle("EmployeeDetails").items.select("*", "Employee_x0020_Name/Title").expand("Employee_x0020_Name/ID").get();
        console.log(items);
        this.setState({ Items: items });
        let html = await this.getHTML(items);
        this.setState({ HTML: html });
      }
      public findData = (id): void => {
        //this.fetchData();
        var itemID = id;
        var allitems = this.state.Items;
        var allitemsLength = allitems.length;
        if (allitemsLength > 0) {
          for (var i = 0; i < allitemsLength; i++) {
            if (itemID == allitems[i].Id) {
              this.setState({
                ID:itemID,
                EmployeeName:allitems[i].Employee_x0020_Name.Title,
                EmployeeNameId:allitems[i].Employee_x0020_NameId,
                HireDate:new Date(allitems[i].HireDate),
                JobDescription:allitems[i].Job_x0020_Description
              });
          }
        }
      }
    
      }
    
      public async getHTML(items) {
        var tabledata = <table className={styles.table}>
          <thead>
            <tr>
              <th>Employee Name</th>
              <th>Hire Date</th>
              <th>Job Description</th>
            </tr>
          </thead>
          <tbody>
            {items && items.map((item, i) => {
              return [
                <tr key={i} onClick={()=>this.findData(item.ID)}>
                  <td>{item.Employee_x0020_Name.Title}</td>
                  <td>{FormatDate(item.HireDate)}</td>
                  <td>{item.Job_x0020_Description}</td>
                </tr>
              ];
            })}
          </tbody>
    
        </table>;
        return await tabledata;
      }
      public _getPeoplePickerItems = async (items: any[]) => {
    
        if (items.length > 0) {
    
          this.setState({ EmployeeName: items[0].text });
          this.setState({ EmployeeNameId: items[0].id });
        }
        else {
          //ID=0;
          this.setState({ EmployeeNameId: "" });
          this.setState({ EmployeeName: "" });
        }
      }
      public onchange(value, stateValue) {
        let state = {};
        state[stateValue] = value;
        this.setState(state);
      }
      private async SaveData() {
        let web = Web(this.props.webURL);
        await web.lists.getByTitle("EmployeeDetails").items.add({
    
          Employee_x0020_NameId:this.state.EmployeeNameId,
          HireDate: new Date(this.state.HireDate),
          Job_x0020_Description: this.state.JobDescription,
    
        }).then(i => {
          console.log(i);
        });
        alert("Created Successfully");
        this.setState({EmployeeName:"",HireDate:null,JobDescription:""});
        this.fetchData();
      }
      private async UpdateData() {
        let web = Web(this.props.webURL);
        await web.lists.getByTitle("EmployeeDetails").items.getById(this.state.ID).update({
    
          Employee_x0020_NameId:this.state.EmployeeNameId,
          HireDate: new Date(this.state.HireDate),
          Job_x0020_Description: this.state.JobDescription,
    
        }).then(i => {
          console.log(i);
        });
        alert("Updated Successfully");
        this.setState({EmployeeName:"",HireDate:null,JobDescription:""});
        this.fetchData();
      }
      private async DeleteData() {
        let web = Web(this.props.webURL);
        await web.lists.getByTitle("EmployeeDetails").items.getById(this.state.ID).delete()
        .then(i => {
          console.log(i);
        });
        alert("Deleted Successfully");
        this.setState({EmployeeName:"",HireDate:null,JobDescription:""});
        this.fetchData();
      }
    
      public render(): React.ReactElement<IHelloWorldProps> {
        return (
          <div>
            <h1>CRUD Operations With ReactJs</h1>
            {this.state.HTML}
            <div className={styles.btngroup}>
              <div><PrimaryButton text="Create" onClick={() => this.SaveData()}/></div>
              <div><PrimaryButton text="Update" onClick={() => this.UpdateData()} /></div>
              <div><PrimaryButton text="Delete" onClick={() => this.DeleteData()}/></div>
            </div>
            <div>
              <form>
                <div>
                  <Label>Employee Name</Label>
                  <PeoplePicker
                    context={this.props.context}
                    personSelectionLimit={1}
                    // defaultSelectedUsers={this.state.EmployeeName===""?[]:this.state.EmployeeName}
                    required={false}
                    onChange={this._getPeoplePickerItems}
                    defaultSelectedUsers={[this.state.EmployeeName?this.state.EmployeeName:""]}
                    showHiddenInUI={false}
                    principalTypes={[PrincipalType.User]}
                    resolveDelay={1000}
                    ensureUser={true}
                  />
                </div>
                <div>
                  <Label>Hire Date</Label>
                  <DatePicker maxDate={new Date()} allowTextInput={false} strings={DatePickerStrings} value={this.state.HireDate} onSelectDate={(e) => { this.setState({ HireDate: e }); }} ariaLabel="Select a date" formatDate={FormatDate} />
                </div>
                <div>
                  <Label>Job Description</Label>
                  <TextField value={this.state.JobDescription} multiline onChanged={(value) => this.onchange(value, "JobDescription")} />
                </div>
    
              </form>
            </div>
          </div>
        );
      }
}
export const DatePickerStrings: IDatePickerStrings = {
    months: ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'],
    shortMonths: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'],
    days: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'],
    shortDays: ['S', 'M', 'T', 'W', 'T', 'F', 'S'],
    goToToday: 'Go to today',
    prevMonthAriaLabel: 'Go to previous month',
    nextMonthAriaLabel: 'Go to next month',
    prevYearAriaLabel: 'Go to previous year',
    nextYearAriaLabel: 'Go to next year',
    invalidInputErrorMessage: 'Invalid date format.'
  };
  export const FormatDate = (date): string => {
    console.log(date);
    var date1 = new Date(date);
    var year = date1.getFullYear();
    var month = (1 + date1.getMonth()).toString();
    month = month.length > 1 ? month : '0' + month;
    var day = date1.getDate().toString();
    day = day.length > 1 ? day : '0' + day;
    return month + '/' + day + '/' + year;
  };

Download SharePoint framework crud operations using react

You can download the SharePoint framework crud operations using react project.

Once you unzip, then run the below commands on the same folder.

npm i 
npm i @pnp/sp
npm i @pnp/spfx-controls-react

Then you can run the below command that will open the local workbench.

gulp serve

While the local workbench is running, you can open the SharePoint workbench, and then add the HelloWorld web part.

https://<tenantname>.sharepoint.com/sites/<SiteName>/_layouts/15/workbench.aspx

Once you add the web part, you can see the output like below:

SharePoint framework crud operations using react
SharePoint framework crud operations using react

Deploy SharePoint framework crud operations using react solution

If you want to deploy the SPFx client-side web part to your SharePoint Online app catalog site or site collection app catalog, then run the below commands, that will create the .sppkg file under the SharePoint folder in the SPFx crud operations using react solution.

gulp bundle --ship

gulp package-solution --ship

Once the package got created, simply drag and drop the .sppkg file to the Apps for SharePoint folder in the App catalog site.

SharePoint Framework crud operations – Video tutorial

I have created a complete video tutorial on SharePoint Framework crud operations using react. I would like you to follow the video tutorial along while creating the SPFx solution.

You may like the following SPFx tutorials:

In this tutorial, we learned in detail on SharePoint framework crud operations using react and the below things:

  • SharePoint framework crud operations using react
  • SPFx crud operations using react – Create the SPFx solution
  • SPFx crud operations using react – Install PnP/SP and PnP SPFx Controls
  • SharePoint framework crud operations – Display SharePoint Online List Items
  • SPFx crud operation using reactjs – Insert item to SharePoint Online list
  • SharePoint framework crud operations – Update List item using Reactjs
  • SPFx crud operations using react pnp – Delete Item from SharePoint Online
  • SPFx crud operations using react – Complete Code
  • Download SharePoint framework crud operations using react
  • Deploy SharePoint framework crud operations using react solution
  • SharePoint Framework crud operations – Video tutorial
  • context giving error in CrudReact.tsx
    src/webparts/crudReactDemo/components/CRUDReact.tsx(171,21): error TS2322: Type ‘WebPartContext’ is not assignable to type ‘BaseComponentContext’.
    [15:05:50] [tsc] Types have separate declarations of a private property ‘_serviceScope’.
    [15:05:50] Error – ‘tsc’ sub task errored after 19 s
    exited with code 2

    Please give me the solution

  • First of all, thanks for the tutorial!!!
    I have a problem when i enter some data in the input field, it becomes read only and shows this text > [object Object]
    You know why?

    • Please check if your onChange function is used using arrow function. convert it into normal function

      private getName(e): void {
      this.setState({userName:e.target.value});
      }

  • This is a fine tutorial and covers most of the issues I have in converting CEWP web parts to SPFx. I have been unable to correct three problems in the tutorial all in the tsx file: 1. styles.table in the var tabledata: table is unknown; 2. btngroup is unknown in styles.btngroup; and 3. context is unknown in context={this.props.context}. I face CRUD and PeoplePicker conversion issues in my CEWP apps. Your advice would be appreciated.

  • >