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:
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:
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
Then it will take sometime and create the solution, you can see the successful message like below:
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
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>.
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();
}
- Insert item to SharePoint Online list using JavaScript Object Model
- Insert/Add item to SharePoint Online list using PowerShell
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.
- Delete All items from the SharePoint List using PnP core CSOM Library Programmatically
- Create, Update and Delete SharePoint List using Rest API
- Delete list items created before N days using PowerShell in SharePoint Online
- Delete all items from SharePoint list programmatically using JSOM
- Remove all items from a SharePoint Online list using PnP PowerShell
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:
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:
- Create and deploy SharePoint Framework (SPFx) listview command set extension
- Create and Deploy SharePoint Framework (SPFx) extension field customizer
- SharePoint Framework (SPFx) Extensions Application Customizer Example
- Retrieve SharePoint list items using SharePoint framework (SPFx)
- SharePoint client-side web part configurable properties in Property Pane using spfx
- How to Create Site Columns, Content Type and Custom List using SharePoint Framework
- SPFx – Bind dropdown list from SharePoint list using PnP
- How to get user details using Microsoft Graph API in SPFx
- SharePoint online spfx script editor web part
- How to Send Email with Attachments using Graph API in SPFx (React JS)
- office-ui-fabric-react combobox example in SharePoint Framework
- Call Azure Function From SharePoint Framework
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
I am Bijay a Microsoft MVP (10 times – My MVP Profile) in SharePoint and have more than 17 years of expertise in SharePoint Online Office 365, SharePoint subscription edition, and SharePoint 2019/2016/2013. Currently working in my own venture TSInfo Technologies a SharePoint development, consulting, and training company. I also run the popular SharePoint website EnjoySharePoint.com
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.
When I click on row why peoplepicker field is not being bind