PnP React Hooks
PnP React Hooks is a wrapper library for PnPjs, provides configurable React hooks for SharePoint API to speed up development for simple SPFx webparts and components.
Example usage:
import * as React from "react";
import { useListItems, useCurrentUser } from "pnp-react-hooks";
export const ExampleComponent = () => {
const currentUser = useCurrentUser();
const items = useListItems("My List", {
query: {
select: ["Title", "Id", "Author/Title"],
expand: ["Author"],
filter: `Author eq ${currentUser?.Id}`
},
disabled: !currentUser
});
return (<ul>
{items?.map(item => (<li key={item.Id}>{item.Title}</li>))}
</ul>);
};
Installation
npm install pnp-react-hooks @pnp/sp react
@pnp/sp
and react
packages are peer dependencies.
Peer dependency | Supported versions |
---|---|
@pnp/sp | 4.1.0 or later |
react | 16.9.* to 18.*.* |
Features
- Build simple web parts quickly with less code.
- TypeScript support.
- Automatically tracks parameter changes and refreshes data as needed.
- Easy to tree-shake unused code with modern JS bundlers.
- Can be configured for multiple sites with an option provider.
- Supports PnPjs behaviors.
Questions and Suggestions
If you find any issue or have a suggestion on how project can be improved feel free to create an issue on Github.
Getting Started
SPFx
- Install
pnp-react-hooks
and@pnp/sp
packages to your SPFx webpart project.
npm install pnp-react-hooks @pnp/sp
- Update module imports,
onInit()
andrender()
functions on<YourWebpartName>.tsx
file.
PnpReactHookExamplesWebPart.ts
// <Other Webpart imports>
// Import pnp-react-hooks helper function and option type
import { PnpHookGlobalOptions, createProviderElement } from 'pnp-react-hooks';
// import PnPjs
import { spfi, SPFx} from '@pnp/sp';
export default class PnpReactHookExamplesWebPart extends BaseClientSideWebPart<IPnpReactHookExamplesWebPartProps>
{
private _isDarkTheme: boolean = false;
private _environmentMessage: string = '';
private _theme: IReadonlyTheme;
private _hookOptions: PnpHookGlobalOptions;
// Create onInit function to initialize options.
protected onInit(): Promise<void>
{
return this._getEnvironmentMessage().then(message =>
{
this._environmentMessage = message;
// Initialize PnPjs sp context.
const sp = spfi().using(SPFx(this.context));
// Setup your default PnP React hooks options.
this._hookOptions = {
sp: sp,
disabled: "auto"
};
});
}
public render(): void
{
const element: React.ReactElement<IPnpReactHookExamplesProps> = React.createElement(
PnpReactHookExamples,
{
description: this.properties.description,
}
);
// Use helper function to create React elements.
const rootElement = createProviderElement(this._hookOptions, element);
// Render root element.
ReactDom.render(rootElement, this.domElement);
}
}
- Start using hooks in your webpart components.
PnpReactHookExamples.tsx
import * as React from 'react';
import { IPnpReactHookExamplesProps } from './IPnpReactHookExamplesProps';
import { useCurrentUser } from "pnp-react-hooks";
const PnpReactHookExamples = (props: IPnpReactHookExamplesProps) => {
const me = useCurrentUser({
query: {
select: ["Title"]
}
});
return (<div>{me?.Title}</div>);
};
export default PnpReactHookExamples;
Common Hook Options
All hook options have the following common properties:
disabled: Disables hook execution if supplied value or predicate function result is true
. It also supports "auto"
which handles the common cases like null
list name, undefined
user name etc.
query: OData query parameters supported by resource type. Automatically tracked for changes with deep comparison.
For example, the following query1
and query2
are considered as equal and they won't cause any re-render.
const query1 = {
select: ["Title", "Id", "Lookup/Id"],
expand: ["Lookup"]
}
const query2 = {
expand: ["Lookup"]
select: ["Id", "Lookup/Id", "Title"],
}
keepPreviousState: When enabled, hook does not reset it's current state to undefined
before sending a new request.
sp: Overrides PnpJs SPFI instance. Default uses context-provided instance.
behaviors: Sets PnpJs pipeline behaviors to each request.
error: Error handling mode or custom error callback. Use ErrorMode.Default
(0
) for throwing error, ErrorMode.Suppress
(1
) for ignoring the errors.
type PnpHookOptions = {
disabled?: "auto" | boolean | (...args[]) => boolean;
query?: {
expand?: string[];
select?: string[];
// Extra properties are available for collection types.
top?: number;
orderBy?: string;
orderyByAscending?: boolean;
skip?: number;
filter?: string;
},
keepPreviousState?: boolean;
sp?: SPFI;
behaviors?: TimelinePipe<any>[];
error?: 0 | 1 | (err:Error) => void;
}
Option Provider
All hooks can be configured with PnpHookOptionProvider
component.
SP Hooks use options from the nearest parent provider similar to how React contexts works.
import * as React from "react";
import { useWebInfo, PnpHookOptionProvider, PnpHookGlobalOptions } from "pnp-react-hooks";
import { Caching } from "@pnp/queryable";
import { spfi, SPBrowser } from "@pnp/sp";
/** @type{PnpHookGlobalOptions} **/
const options = {
disabled: "auto",
keepPreviousState: true,
error: console.debug,
sp: spfi().using(SPBrowser())
};
/** @type{PnpHookGlobalOptions} **/
const cachedOptions = {
disabled: "auto",
keepPreviousState: true,
error: console.debug,
sp: spfi().using(SPBrowser(), Caching())
};
export function Main() {
return(
<>
<PnpHookOptionProvider value={options}>
<CurrentWebInfo />
<UserInfo />
</PnpHookOptionProvider>
<PnpHookOptionProvider value={cachedOptions}>
<CurrentWebInfo />
<UserInfo />
</PnpHookOptionProvider>
</>
);
}
export function CurrentWebInfo() {
const web = useWebInfo();
return <h1>{web?.Title}</h1>;
}
export function UserInfo() {
const user = useCurrentUser();
return <h2>{user?.Title}</h2>;
}
For non-Jsx initializers, PnpHookOptionProvider
can be created with createProviderElement
function.
createProviderElement(options: PnpHOokGlobalOptions, ...children: any[]);
import * as React from "react";
import * as ReactDom from "react-dom";
import { spfi, SPBrowser } from "@pnp/sp";
import { createProviderElement, PnpHookGlobalOptions } from 'pnp-react-hooks';
// create options
const options: PnpHookGlobalOptions = {
sp: spfi("<sharepoint-site-url>").using(SPBrowser()),
disabled: "auto",
error: (err) => console.debug(err)
};
// Create your child elements
const childElement0 = React.createElement(PnpReactHookExamples, { description: "Child 0" });
const childElement1 = React.createElement(PnpReactHookExamples, { description: "Child 1" });
// Create root element with provider
const rootElement = createProviderElement(options, childElement0, childElement1);
ReactDom.render(rootElement, this.domElement);
Created React DOM tree is:
<PnpHookOptionProvider value={options}>
<PnpReactHookExamples description="Child 0" />
<PnpReactHookExamples description="Child 1" />
</PnpHookOptionProvider>
Accessing Options
usePnpHookOptions(): PnpHookGlobalOptions;
Returns options from the nearest PnpHookOptionProvider
.
Example
import { usePnpHookOptions } from "pnp-react-hooks";
function ExampleComponent() {
const options = usePnpHookOptions();
.....
.....
.....
.....
}
Sp Hooks
- useApp
- useApps
- useAttachment
- useAttachments
- useChanges
- useContentTypes
- useCurrentUser
- useFeatures
- useField
- useFields
- useFile
- useFiles
- useFolder
- useFolders
- useFolderTree
- useGroup
- useGroups
- useGroupUser
- useGroupUsers
- useHasPermission
- useIsMemberOf
- useItemComments
- useListAsStream
- useListChangeToken
- useListItem
- useListItems
- useList
- useLists
- useNavigation
- usePageComments
- useProfile
- useRecycleBinItem
- useRecycleBinItems
- useRegionalSetting
- useRoleAssignments
- useRoleDefinition
- useRoleDefinitions
- useSearch
- useSearchUser
- useSite
- useSiteUsers
- useSubWebs
- useUser
- useView
- useViews
- useWebInfo
- useWebProperties
useApp
useApp<T>(appId: string, options?:WebAppOptions, deps?: any[]) : T | null | undefined;
Returns an app details for the given Id.
Examples
Get app from site collections app catalog,
const app = useApp("5ee53613-bc0f-4b2a-9904-b21afd8431a7");
Query app propeties,
const appWithQuery = useApp("5ee53613-bc0f-4b2a-9904-b21afd8431a7", {
query: {
select: ["Title", "Id", "IsEnabled"]
}
});
Get app from tenant app catalog,
const tenantApp = useApp("5ee53613-bc0f-4b2a-9904-b21afd8431a7", {
scope: "tenant"
});
Set scope to site collection explicitly, same as setting scope
to undefined
,
const tenantApp = useApp("5ee53613-bc0f-4b2a-9904-b21afd8431a7", {
scope: "sitecollection"
});
Parameters
Name | Type | Description | Tracked for changes |
---|---|---|---|
appId | string | App UUID string. | Yes |
options? | WebAppOptions | useApp hook options | Partially |
deps? | DependencyList | Hook dependency list. | Yes |
useApps
useApps<T>(options?: WebAppsOptions, deps?: any[]): T[] | null | undefined;
Returns app collection from app catalog.
Examples
Get apps from site collections app catalog,
const apps = useApps();
Get apps from tenants app catalog,
const apps = useApps({
scope: "tenant"
});
Set scope to site collection explicitly,
const apps = useApps({
scope: "sitecollection"
});
Query apps from app catalog,
const filteredApps = useApps({
query: {
select: ["Title", "Id", "IsEnabled"],
filter: "IsEnabled eq true"
}
});
Parameters
Name | Type | Description | Tracked for changes |
---|---|---|---|
options? | WebAppsOptions | useApps hook options | Partially |
deps? | DependencyList | Hook dependency list. | Yes |
useAttachment
useAttachment(
attachmentName:string,
itemId:number,
list:string,
options?: AttachmentInfoOptions,
deps?:any[]): IAttachmentInfo | null | undefined;
useAttachment(
attachmentName:string,
itemId:number,
list:string,
options?: AttachmentTextOptions,
deps?:any[]): string | null | undefined;
useAttachment(
attachmentName:string,
itemId:number,
list:string,
options?: AttachmentBlobOptions,
deps?:any[]): Blob | null | undefined;
useAttachment(
attachmentName:string,
itemId:number,
list:string,
options?: AttachmentBufferOptions,
deps?:any[]): ArrayBuffer | null | undefined;
Returns an attachment info or attachment content from item.
Examples
Get attachment info,
const attachmentProps = useAttachment("my-attachment.txt", 12, "My List");
Query attachment info properties,
const attachmentProps = useAttachment("my-attachment.txt", 12, "My List"), {
query: {
select: ["Title", "Id"]
}
});
Get attachment content as Blob
,
const contentAsBlob = useAttachment("my-attachment.txt", 12, "My List", {
type: "blob"
});
Get attachment content as ArrayBuffer
,
const contentAsBuffer = useAttachment("my-attachment.txt", 12, "My List", {
type: "buffer"
});
Get attachment content as string
,
const contentAsText = useAttachment("my-attachment.txt", 12, "My List", {
type: "text"
});
Parameters
Name | Type | Description | Tracked for changes |
---|---|---|---|
attachmentName | string | Attachment name | Yes |
itemId | number | List item ID | Yes |
list | string | Target list UUID or title | Yes |
options? | AttachmentInfoOptions | AttachmentBlobOptions | AttachmentTextOptions | AttachmentBufferOptions | useAttachment hook options | Partially |
deps? | DependencyList | Hook dependency list. | Yes |
useAttachments
useAttachments(
itemId: number,
list: string,
options?: ItemAttachmentsOptions,
deps: any[]): IAttachmentInfo[] | null | undefined;
Returns all attachments from an item.
Examples
Get all attachments from an item,
const attachments = useAttachments(10, "My List");
Query list items attachments,
const filteredAttachments = useAttachments(10, "5ee53613-bc0f-4b2a-9904-b21afd8431a7", {
query: {
select: ["Name", "Id"],
filter: "substringof('.pdf', Name) eq true"
}
});
Parameters
Name | Type | Description | Tracked for changes |
---|---|---|---|
itemId | number | List item ID | Yes |
list | string | Target list UUID or title | Yes |
options? | ItemAttachmentsOptions | useAttachments hook options | Partially |
deps? | DependencyList | Hook dependency list. | Yes |
useChanges
useChanges<T>(
changeQuery: IChangeQuery,
options?: ChangesOptions,
deps?: any[]): T[] | null | undefined;
Returns web or list change collection. Use ChangesOptions.list
property to get list changes instead of web changes.
Examples
Get web changes,
const changeQuery = {
Add:true,
Alert:true,
ChangeTokenEnd: { StringValue: "some end token string" },
ChangeTokenStart: { StringValue: "some start token string" }
};
const webChanges = useChanges(myQuery, undefined, [
myQuery?.ChangeTokenStart?.StringValue,
myQuery?.ChangeTokenEnd?.StringValue
]);
Get list changes by using list title and UUID,
const listChangeQuery = {
Add:true,
Update:true,
Delete:true,
ChangeTokenEnd: { StringValue: "some end token string" },
ChangeTokenStart: { StringValue: "some start token string" }
};
// getting list changes by list title
const listChanges = useChanges(
listChangeQuery,
{ list: "My List Title" },
[
myQuery?.ChangeTokenStart?.StringValue,
myQuery?.ChangeTokenEnd?.StringValue
]
);
// getting list changes by list Id
const anotherListChanges = useChanges(
listChangeQuery,
{ list: "61ca5ff8-f553-4d51-a761-89225b069a4f" },
[
myQuery?.ChangeTokenStart?.StringValue,
myQuery?.ChangeTokenEnd?.StringValue
]
);
Parameters
Name | Type | Description | Tracked for changes |
---|---|---|---|
changeQuery | IChangeQuery | Change query object | No |
options? | ChangesOptions | useChanges hook options | Partially |
deps? | DependencyList | Hook dependency list | Yes |
useContentTypes
useContentTypes(
options?: ContentTypeOptions,
deps?: any[]): IContentTypeInfo[] | null | undefined;
Returns content types of web or list. Use ContentTypeOptions.list
property to get list content types instead of web content types.
Examples
Get web content types,
const webContentTypes = useContentTypes();
Get list content types by list Id,
const listContentTypes = useContentTypes({
list: "5ee53613-bc0f-4b2a-9904-b21afd8431a7"
});
Get list content types by list title,
const listContentTypes = useContentTypes({
list: "My List Title"
});
Parameters
Name | Type | Description | Tracked for changes |
---|---|---|---|
options? | ContentTypeOptions | useContentTypes hook options. | Partially |
deps? | DependencyList | Hook dependency list | Yes |
useCurrentUser
useCurrentUser(
options?: CurrentUserInfoOptions,
deps?: any[]): ISiteUserInfo | null | undefined;
Returns current user information.
Examples
Get basic user properties,
const userAllProps = useCurrentUser();
Get user properties with query,
const user = useCurrentUser({
query: {
select: ["Title", "Id", "LoginName"]
}
});
Parameters
Name | Type | Description | Tracked for changes |
---|---|---|---|
options? | CurrentUserInfoOptions | useCurrentUser hook options. | Partially |
deps? | DependencyList | Hook dependency list | Yes |
useFeatures
useFeatures(
options?: FeaturesOptions,
deps?: any[]): IFeatureInfo[] | null | undefined;
Returns site or web feature collection. Scope type can be defined in FeaturesOptions.scope
property.
Examples
Get web features,
const webFeatures = useFeatures();
Get site features,
const siteFeatures = useFeatures({
scope: "site"
});
Parameters
Name | Type | Description | Tracked for changes |
---|---|---|---|
options? | FeaturesOptions | useFeature hook options | Partially |
deps? | DependencyList | Hook dependency list. | Yes |
useField
useField(
fieldId: string,
options?: FieldOptions,
deps? any[]): IFieldInfo | null | undefined;
Returns a field from web or list.
Examples
Get web field info,
const webFields = useField("5ee53613-bc0f-4b2a-9904-b21afd8431a7");
Get list field info,
const listFields = useField("MyCustomFieldInternalName", {
list: "5ee53613-bc0f-4b2a-9904-b21afd8431a7"
});
Parameters
Name | Type | Description | Tracked for changes |
---|---|---|---|
fieldId | string | Field internal name or Id | Yes |
options? | FieldOptions | useField hook options | Partially |
deps? | DependencyList | Hook dependency list. | Yes |
useFields
useFields(
options?: FieldsOptions,
deps?: any[]): IFieldInfo[] | null | undefined;
Returns field collection from web or list. Use FieldsOptions.list
property to set target list.
Examples
Get web fields,
const webFields = useFields();
Get list fields,
const listFields = useFields({
list: "5ee53613-bc0f-4b2a-9904-b21afd8431a7"
});
Query fields,
const listFields = useFields({
list: "My List Title",
query:{
select: ["InternalName", "Title", "Id"]
}
});
Parameters
Name | Type | Description | Tracked for changes |
---|---|---|---|
options? | FieldsOptions | useFields hook options | Partially |
deps? | DependencyList | Hook dependency list. | Yes |
useFile
useFile(
fileId: string,
options?: FileInfoOptions,
deps?: any[]): IFileInfo | null | undefined;
useFile(
fileId: string,
options?: FileBlobOptions,
deps?: any[]): Blob | null | undefined;
useFile(
fileId: string,
options?: FileTextOptions,
deps?: any[]): string | null | undefined;
useFile(
fileId: string,
options?: FileBufferOptions,
deps?: any[]): ArrayBuffer | null | undefined;
Returns a file from file collection.
Examples
Get file info by ID,
const fileInfo = useFile("5ee53613-bc0f-4b2a-9904-b21afd8431a7");
Get file info by server relative path,
const assetInfo = useFile("/sites/mysite/SiteAssets/example.png");
Get file content as Blob
,
const fileContentAsBlob = useFile("5ee53613-bc0f-4b2a-9904-b21afd8431a7", {
type: "blob"
});
Get file content as ArrayBuffer
,
const fileContentAsBuffer = useFile("5ee53613-bc0f-4b2a-9904-b21afd8431a7", {
type: "buffer"
});
Get file content as string
,
const fileContentAsText = useFile("5ee53613-bc0f-4b2a-9904-b21afd8431a7", {
type: "text"
});
Parameters
Name | Type | Description | Tracked for changes |
---|---|---|---|
fileId | string | file UUID or server relative path | Yes |
options? | FileInfoOptions | FileBlobOptions | FileTextOptions | FileBufferOptions | useFile hook options | Partially |
deps? | DependencyList | Hook dependency list. | Yes |
useFiles
useFiles(
folderId: string,
options?: FilesOptions,
deps?: any[]): IFileInfo[] | null | undefined;
Returns file collection from folder.
Examples
Get all files from a folder by UUID,
const files = useFiles("5ee53613-bc0f-4b2a-9904-b21afd8431a7");
Get all files from a folder by server relative URL,
const siteAssetsFiles = useFiles("/sites/mysite/SiteAssets", {
query: {
select: ["Id", "Name", "ServerRelativeUrl", "Author/Title"]
expand: ["Author"]
}
});
Parameters
Name | Type | Description | Tracked for changes |
---|---|---|---|
folderId | string | Folder UUID or server relative URL | Yes |
options? | FilesOptions | useFiles hook options | Partially |
deps? | DependencyList | Hook dependency list. | Yes |
useFolder
useFolder(
folderId: string,
options?: FolderOptions,
deps?: any[]): IFolderInfo | null | undefined;
Return a folder.
Examples
Get folder by Id,
const folder = useFolder("5ee53613-bc0f-4b2a-9904-b21afd8431a7");
Get folder by server relative url,
const siteAssets = useFolder("/sites/mysite/SiteAssets", {
query: {
select: ["Id", "Name", "ServerRelativeUrl"]
}
});
Parameters
Name | Type | Description | Tracked for changes |
---|---|---|---|
folderId | string | Folder UUID or server relative path | Yes |
options? | FolderOptions | useFolder hook options | Partially |
deps? | DependencyList | Hook dependency list. | Yes |
useFolders
useFolders(
options?: FoldersOptions,
deps?: any[]): IFolderInfo[] | null | undefined;
Returns folders from root. Use FoldersOptions.rootFolderId
property to change root folder.
Examples
Get folders from webs root,
const rootFolders = useFolders();
Get folders from different folder,
const folders = useFolders({
rootFolderId: "5ee53613-bc0f-4b2a-9904-b21afd8431a7"
});
const folders = useFolders({
rootFolderId: "/sites/mysite/SiteAssets"
});
Query folders,
const filteredFolders = useFolders({
query:{
select: ["Id", "Title"],
filter: "substringof('SiteAssets', Title) eq true"
}
});
Parameters
Name | Type | Description | Tracked for changes |
---|---|---|---|
options? | FoldersOptions | useFolders hook options | Partially |
deps? | DependencyList | Hook dependency list. | Yes |
useGroup
useGroup(
groupId: string | number,
options?: GroupOptions,
deps?: any[]): ISiteGroupInfo | null | undefined;
Returns a group from group collection.
Examples
Get group info by Id,
const group = useGroup(10);
Get group info by name
const mySpGroup = useGroup("My SharePoint Group");
Query group properties,
const mySpGroup = useGroup("My SharePoint Group", {
query: {
select: ["Title", "Id"]
}
});
Parameters
Name | Type | Description | Tracked for changes |
---|---|---|---|
groupId | string | number | Group Id or name | Yes |
options? | GroupOptions | useApps hook options | Partially |
deps? | DependencyList | Hook dependency list. | Yes |
useGroups
useGroups(options?: GroupsOptions, deps?: any[]): ISiteGroupInfo[] | null | undefined;
Returns group collection. Use GroupsOptions.userId
property to get groups for specific user.
Examples
Get all groups,
const groups = useGroups();
Get groups for a specific user,
const userGroups = useGroups({
userId: 20
});
const userGroupsByEmail = useGroups({
userId: "user@example.onmicrosoft.com"
});
const userGroupsByLoginName = useGroups({
userId: "i:0#.f|membership|user@example.onmicrosoft.com"
});
Parameters
Name | Type | Description | Tracked for changes |
---|---|---|---|
options? | GroupsOptions | useGroups hook options | Partially |
deps? | DependencyList | Hook dependency list. | Yes |
useGroupUser
useGroupUser(
groupId: string | number,
userId: string | number,
options?: GroupUserOptions,
deps?: any[]): ISiteUserInfo | null | undefined;
Returns an user from specific group user collection.
Examples
const groupUser = useGroupUser(10, 27);
const groupUser = useGroupUser("My SharePoint Group", 27);
const groupUser = useGroupUser("My SharePoint Group", "user@example.onmicrosoft.com");
const groupUser = useGroupUser("My SharePoint Group", "i:0#.f|membership|user@example.onmicrosoft.com");
Parameters
Name | Type | Description | Tracked for changes |
---|---|---|---|
groupId | string | number | Group name or Id | Yes |
userId | string | number | User email, login name or Id | Yes |
options? | WebAppsOptions | useApps hook options | Partially |
deps? | DependencyList | Hook dependency list. | Yes |
useGroupUsers
useGroupUsers(
groupId: `string` | `number`,
options?: GroupUsersOptions,
deps?: any[]): ISiteUserInfo[] | null | undefined;
Returns user collection from specific group.
Examples
Get group users,
const myGroupUsers = useGroupUsers(10);
const myGroupUsers = useGroupUsers("My SharePoint Group");
Query group users,
const filteredGroupUsers = useGroupUsers("My SharePoint Group", {
query:{
select: ["LoginName", "Title"],
filter: "IsSiteAdmin eq false"
}
});
Parameters
Name | Type | Description | Tracked for changes |
---|---|---|---|
groupId | string | number | Group Id or name | Yes |
options? | GroupUsersOptions | useGroupUsers hook options | Partially |
deps? | DependencyList | Hook dependency list. | Yes |
useHasPermission
useHasPermission(
permissionKinds: PermissionKind | PermissionKind[],
options?: UserPermissionOptions,
deps?): boolean | null | undefined;
Returns true
if user has permission on scope. If not returns false
. Use
UserPermissionOptions.userId
for another user and UserPermissionOptions.scope
for permission scope. Default is current user permission on current web scope.
Examples
Check current users web permissions,
import { PermissionKind } from "@pnp/sp/security";
import { useHasPermission } from "pnp-react-hooks";
const permissions = PermissionKind.ViewListItems | PermissionKind.ViewPages
const hasPermission = useHasPermission(permissions);
Check another users permission on web,
import { PermissionKind } from "@pnp/sp/security";
import { useHasPermission } from "pnp-react-hooks";
const permissions = PermissionKind.ViewListItems | PermissionKind.ViewPages
const userHasPermission = useHasPermission(permissions, {
userId: "user@example.onmicrosoft.com"
});
Check list permissions,
import { PermissionKind } from "@pnp/sp/security";
import { useHasPermission } from "pnp-react-hooks";
const permissions = PermissionKind.ViewListItems | PermissionKind.ViewPages
const hasPermission = useHasPermission(permissions, {
scope: {
list: "My List Title"
}
});
Check item permissions,
import { PermissionKind } from "@pnp/sp/security";
import { useHasPermission } from "pnp-react-hooks";
const permissions = PermissionKind.ViewListItems | PermissionKind.ViewPages
const hasPermission = useHasPermission(permissions, {
scope: {
list: "My List Title",
item: 12
}
});
Parameters
Name | Type | Description | Tracked for changes |
---|---|---|---|
permissionKinds | PermissionKind | PermissionKind[] | SP permission kind array or value | Yes |
options? | UserPermissionOptions | useHasPermission hook options | Partially |
deps? | DependencyList | Hook dependency list. | Yes |
useIsMemberOf
useIsMemberOf(
groupId: string | number,
options?: IsMemberOfOptions,
deps?: any[]): [boolean, ISiteGroupInfo];
Returns users membership info for the specified group. Use IsMemberOfOptions.userId
property to check another user. Default is current user.
Examples
Get current users membership info,
const [isMember, groupInfo] = useIsMemberOf(10);
Get different users membership info,
const [isMember, groupInfo] = useIsMemberOf("My SharePoint Group", {
userId: "user@example.onmicrosoft.com"
});
const [isMember, groupInfo] = useIsMemberOf("My SharePoint Group", {
userId: 25
});
const [isMember, groupInfo] = useIsMemberOf(10, {
userId: "i:0#.f|membership|user@example.onmicrosoft.com"
});
Parameters
Name | Type | Description | Tracked for changes |
---|---|---|---|
groupId | string | Group name or Id | Yes |
options? | IsMemberOfOptions | useIsMemberOf hook options | Partially |
deps? | DependencyList | Hook dependency list. | Yes |
useItemComments
useItemComments(
itemId: number,
list: string,
options?: ItemCommentsOptions,
deps?: any[]): ICommentInfo[] | null | undefined;
Returns comments for specific list item.
Examples
Get list items comments,
const comments = useItemComments(12, "My List Title");
const comments = useItemComments(12, "5ee53613-bc0f-4b2a-9904-b21afd8431a7");
Parameters
Name | Type | Description | Tracked for changes |
---|---|---|---|
itemId | number | Item Id | Yes |
list | string | List UUID or title | Yes |
options? | ItemCommentsOptions | useItemComments hook options | Partially |
deps? | DependencyList | Hook dependency list. | Yes |
useListAsStream
useListAsStream(
list: string,
parameters: RenderListParameters,
options?: ListAsStreamOptions,
deps?: any[]): IRenderListDataAsStreamResult | null | undefined;
Returns data for the specified query view.
Examples
Basic usage
const renderData = useListAsStream("5ee53613-bc0f-4b2a-9904-b21afd8431a7", {
dataParameters: {
Paging: "TRUE",
RenderOptions: RenderListDataOptions.ListData
},
dataOverrideParameters: {
PageFirstRow: "1",
PageLastRow: "30",
},
useQueryParameters: true
}
);
Parameters
Name | Type | Description | Tracked for changes |
---|---|---|---|
list | string | List UUID or title | Yes |
parameters | RenderListParameters | Render parameters | No |
options? | ListAsStreamOptions | useListAsStream hook options | Partially |
deps? | DependencyList | Hook dependency list. | Yes |
useListChangeToken
useListChangeToken(
list: string,
options?: ListTokenOptions,
deps?: any[]): IChangeTokenInfo | null | undefined;
Returns lists current change token and last modified dates.
Examples
Get list change tokens,
const changeDetails = useListChangeToken("5ee53613-bc0f-4b2a-9904-b21afd8431a7");
const changeDetails = useListChangeToken("My List Title");
Parameters
Name | Type | Description | Tracked for changes |
---|---|---|---|
list | string | List UUID or title | Yes |
options? | ListTokenOptions | useListChangeToken hook options | Partially |
deps? | DependencyList | Hook dependency list. | Yes |
Remarks
You can also use useList
to get exact same change info.
const listInfo = useList("5ee53613-bc0f-4b2a-9904-b21afd8431a7", {
query: {
select: [
"CurrentChangeToken",
"LastItemDeletedDate",
"LastItemModifiedDate",
"LastItemUserModifiedDate" ]
}
});
useListItem
useListItem<T>(
itemId: number,
list: string,
options?: listItemOptions,
deps?: any[]): T | null | undefined;
Returns an item from specified list.
Examples
Get a list item,
const item = useListItem(10, "5ee53613-bc0f-4b2a-9904-b21afd8431a7");
Get a list item with query and custom type,
export interface MyItem {
Id: number;
Title: string;
Created: string;
Modified: string;
Author : {
Title: string;
}
}
const myItem = useListItem<MyItem>(10, "My List Title", {
query: {
select: ["Title", "Id", "Author/Title", "Created", "Modified"],
expand: ["Author"]
}
});
Parameters
Name | Type | Description | Tracked for changes |
---|---|---|---|
itemId | number | Item Id | Yes |
list | string | List UUID or title | Yes |
options? | ListItemOptions | useListItem hook options | Partially |
deps? | DependencyList | Hook dependency list. | Yes |
useListItems
useListItems<T>(
list: string,
options?: ListItemsOptions,
deps?: any[]): T[] | null | undefined;
useListItems<T>(
list: string,
options?: PagedItemsOptions,
deps?: any[]): [T[] | null | undefined, nextPageDispatch, boolean];
useListItems<T>(
list: string,
options?: AllItemsOptions,
deps?: any[]): T[] | null | undefined;
Examples
Get list items,
const items = useListItems("My List Title");
Query list items,
const myItems = useListItems<MyItem>("5ee53613-bc0f-4b2a-9904-b21afd8431a7", {
query: {
select: ["Title", "Id", "Author/Title", "Created", "Modified"],
expand: ["Author"]
},
mode: ListItemsMode.Default // 0
});
Get list items with custom paging,
const [page, nextPage, done] = useListItems("My List Title", {
mode: ListItemsMode.Paged
});
// You can get next page with nextPageDispatch function.
if(!done) {
nextPage();
// Optionally pass a callback function.
nextPage((data) => console.debug(data));
}
Get all items without 5000 item limit (Not recommended for most cases),
const items = useListItems("My List Title", {
mode: ListItemsMode.All // 1
});
Parameters
Name | Type | Description | Tracked for changes |
---|---|---|---|
list | string | List UUID or Title | Yes |
options? | ListItemsOptions | PagedListItems | AllListItems | useListItems hook options | Partially |
deps? | DependencyList | Hook dependency list. | Yes |
useList
useList(
list: string,
options?: ListOptions,
deps?: any[]): IListInfo | null | undefined;
Return a list from list collection.
Examples
Get list info,
const listInfo = useList("5ee53613-bc0f-4b2a-9904-b21afd8431a7");
Query list properties,
const myList = useList("My List Title", {
query: {
select: ["Title", "Id"],
filter: "ItemCount eq 0"
}
});
Parameters
Name | Type | Description | Tracked for changes |
---|---|---|---|
list | string | List UUID or title | Yes |
options? | ListOptions | useList hook options | Partially |
deps? | DependencyList | Hook dependency list. | Yes |
useLists
useLists(options?: ListsOptions, deps?: any[]): IListInfo[] | null | undefined;
Returns list collection.
Examples
Get site lists,
const listInfo = useLists();
Query site lists,
const emptyLists = useList({
query: {
select: ["Title", "Id"],
filter: "ItemCount eq 0"
}
});
Parameters
Name | Type | Description | Tracked for changes |
---|---|---|---|
options? | ListsOptions | useLists hook options | Partially |
deps? | DependencyList | Hook dependency list. | Yes |
useNavigation
useNavigation(
options?: NavigationOptions,
deps?: any[]): INavNodeInfo[] | null | undefined;
Returns web navigation nodes. Use NavigationOptions.type
property to change navigation type. Default is topNavigation
.
Examples
Get top navigation nodes,
const topNav = useNavigation();
// Explicit type
const topNav = useNavigation({
type: "topNavigation"
});
Get quick launch navigation nodes,
const quickLaunch = useNavigation({
type: "quickLaunch"
});
Parameters
Name | Type | Description | Tracked for changes |
---|---|---|---|
options? | NavigationOptions | useNavigation hook options | Partially |
deps? | DependencyList | Hook dependency list. | Yes |
usePageComments
usePageComments(
pageRelativePath: string,
options?: PageCommentsOptions,
deps?: any[]): ICommentInfo[] | undefined | null;
Returns comment collection from page.
Examples
Get page comments,
const pageComments = usePageComments("/sites/mysite/Pages/Home.aspx");
Parameters
Name | Type | Description | Tracked for changes |
---|---|---|---|
pageRelativePath | string | Page server relative path | Yes |
options? | PageCommentsOptions | useApps hook options | Partially |
deps? | DependencyList | Hook dependency list. | Yes |
useProfiles
useProfile<T>(
loginName: string,
options?: ProfileOptions,
deps?: any[]): T | null | undefined;
Returns an user profile for specified login name or email.
Examples
Get profile by user email,
const profileByEmail = useProfile("user@example.onmicrosoft.com");
Get profile by user login name,
const profile = useProfile("i:0#.f|membership|user@example.onmicrosoft.com");
Parameters
Name | Type | Description | Tracked for changes |
---|---|---|---|
loginName | string | User login name or email | Yes |
options? | ProfileOptions | useProfile hook options | Partially |
deps? | DependencyList | Hook dependency list. | Yes |
useRecycleBinItem
useRecycleBinItem(
itemId: string,
options?:RecycleBinItemOptions,
deps?: any[]): IRecycleBinItemObject` | null | undefined;
Returns an item from recycle bin.
Examples
Web recycle bin item
Get item from webs recycle bin,
const item = useRecycleBinItem("3e33c760-dfd2-4107-ac4a-838b169ea3d8");
// Explicit scope type
const item = useRecycleBinItem("3e33c760-dfd2-4107-ac4a-838b169ea3d8", {
scope: "web"
});
Get item from site collections recycle bin,
const item = useRecycleBinItem("3e33c760-dfd2-4107-ac4a-838b169ea3d8", {
scope: "site"
});
Query recycle bin items properties,
const item = useRecycleBinItem("3e33c760-dfd2-4107-ac4a-838b169ea3d8", {
query: {
select: ["Title", "ItemState"],
}
});
Parameters
Name | Type | Description | Tracked for changes |
---|---|---|---|
itemId | string | Item UUID | Yes |
options? | WebAppsOptions | useRecycleBinItem hook options | Partially |
deps? | DependencyList | Hook dependency list. | Yes |
useRecycleBinItems
useRecycleBinItems(
options?: RecycleBinItemsOptions,
deps?: any[]): IRecycleBinItemObject[] | null | undefined;
Returns all recycle bin items.
Examples
Get web recycle bin items,
const items = useRecycleBinItems();
// Explicit scope
const items = useRecycleBinItems({
scope: "web"
});
Get site recycle bin items,
const items = useRecycleBinItems({
scope: "site"
});
Query recycle bin items,
const items = useRecycleBinItems({
query: {
top: 2,
select: ["Title", "ItemState"],
}
});
Parameters
Name | Type | Description | Tracked for changes |
---|---|---|---|
options? | RecycleBinItemsOptions | useRecyclebinItems hook options | Partially |
deps? | DependencyList | Hook dependency list. | Yes |
useRegionalSetting
useRegionalSetting(
options?: RegionalSettingOptions,
deps?: any[]): IRegionalSettingsInfo | null | undefined;
Returns site regional settings.
Examples
Get regional settings,
const regionalSettings = useRegionalSetting();
Parameters
Name | Type | Description | Tracked for changes |
---|---|---|---|
options? | RegionalSettingOptions | useRegionalSettings hook options | Partially |
deps? | DependencyList | Hook dependency list. | Yes |
useRoleAssignments
useRoleAssignments(
options?: RoleAssignmentsOptions,
deps?: any[]): IRoleAssignmentInfo[] | null | undefined;
Returns role assignmets of selected scope. Use RoleAssignmentsOptions.scope
property to change scope. Default is current web.
Examples
Get web role assignments,
const webRolesAssignments = useRoleAssignments();
Get list role assignments,
const myListRoleAssignments = useRoleAssignments({
scope: {
list: "5ee53613-bc0f-4b2a-9904-b21afd8431a7"
}
});
const myListRoleAssignments = useRoleAssignments({
scope: {
list: "My List Title"
}
});
Get item role assignments,
// get list item roles by list title
const listItemRoleAssignments = useRoleAssignments({
scope: {
list: "5ee53613-bc0f-4b2a-9904-b21afd8431a7",
item: 12
}
});
Parameters
Name | Type | Description | Tracked for changes |
---|---|---|---|
options? | RoleAssignmentsOptions | useRoleAssignments hook options | Partially |
deps? | DependencyList | Hook dependency list. | Yes |
useRoleDefinition
useRoleDefinition(
roleDefId: string | number,
options?: RoleDefinitionOptions,
deps?: any[]): IRoleDefinitionInfo | null | undefined;
Returns role definition with the specified identifier.
Examples
Get role definition,
const roleDefById = useRoleDefinition(1073741826);
const roleDefByName = useRoleDefinition("Contribute");
const roleDefByKind = useRoleDefinition({
roleType: RoleTypeKind.EditListItems | RoleTypeKind.ManageLists
});
Query role definition properties,
const roleDef = useRoleDefinition({ roleType: RoleTypeKind.EditListItems }, {
query: {
select: ["Id", "Name", "Description", "Order"]
}
});
Parameters
Name | Type | Description | Tracked for changes |
---|---|---|---|
roleDefId | string | number | Role definition name, Id or RoleTypeKind | Yes |
options? | WebAppsOptions | useRoleDefinition hook options | Partially |
deps? | DependencyList | Hook dependency list. | Yes |
useRoleDefinitions
useRoleDefinitions(
options?:RoleDefinitionsOptions,
deps?: any[]): IRoleDefinitionInfo[] | null | undefined;
Returns role definition collection.
Examples
Get all role definitions,
const roleDefByKind = useRoleDefinitions();
Query role definitions
const filteredroleDef = useRoleDefinitions({
query: {
select: ["Id", "Name", "Description", "Order"],
filter: "Hidden eq false"
}
});
Parameters
Name | Type | Description | Tracked for changes |
---|---|---|---|
options? | RoleDefinitionsOptions | useRoleDefinitions hook options | Partially |
deps? | DependencyList | Hook dependency list. | Yes |
useSearch
useSearch(
searchQuery: string | ISearchQuery,
options?: SearchOptions,
deps?: any[]): [`SpSearchResult` | null | undefined, `GetPageDispatch`]
Conduct search on SharePoint.
Examples
Basic search,
const [results, setPage] = useSearch("search text");
// load next page
setPage(2);
// load page with callback
setPage(3, () => alert("Page Loaded!"));
Advanced search,
const query = {
Querytext: "*",
RowLimit: 5,
RowsPerPage: 5,
SelectProperties: ["Title"]
};
// Using dependency list to react query property changes.
const [results, setPage] = useSearch(query, undefined, [query?.Querytext]);
Parameters
Name | Type | Description | Tracked for changes |
---|---|---|---|
searchQuery | string | ISearchQuery | Search query object or search text | Yes for string , No for ISearchQuery |
options? | SearchOptions | useSearch hook options | Partially |
deps? | DependencyList | Hook dependency list. | Yes |
useSearchUser
useSearchUser(
searchOptions: string | IClientPeoplePickerQueryParameters,
options?: SearchUserOptions,
deps?: any[]): IPeoplePickerEntity[] | null | undefined;
Searches for users or groups with specified search options.
Examples
Search user by text,
// basic usage
const searchResults = useSearchUser("Mark");
Search user by custom query object,
const query = {
AllowEmailAddresses: true,
AllowMultipleEntities: true,
MaximumEntitySuggestions: 25,
PrincipalType: PrincipalType.All,
QueryString: "query text"
};
const searchResults = useSearchUser(query, undefined, [query?.QueryString]);
Parameters
Name | Type | Description | Tracked for changes |
---|---|---|---|
searchOptions | string | IClientPeoplePickerQueryParameters | Search text or query object | Yes for string , No for query object |
options? | SearchUserOptions | useSearchUser hook options | Partially |
deps? | DependencyList | Hook dependency list. | Yes |
useSite
useSite(options?: SiteInfoOptions, deps?: any[]): ISiteInfo | null | undefined;
Returns current site info.
Examples
Get site info details,
const siteInfo = useSite();
Query site info details,
const site = useSite({
query: {
select: ["Title", "Id"]
}
});
Parameters
Name | Type | Description | Tracked for changes |
---|---|---|---|
options? | SiteInfoOptions | useSite hook options | Partially |
deps? | DependencyList | Hook dependency list. | Yes |
useSiteUsers
useSiteUsers(
options?: SiteUsersOptions,
deps?: any[]): ISiteUserInfo[] | null | undefined;
Returns site users.
Examples
Get all site users,
const siteUsers = useSiteUsers();
Query site users,
const topFiveUser = useSiteUsers({
query: {
select: ["Title", "Id", "LoginName"],
top: 5
}
});
Parameters
Name | Type | Description | Tracked for changes |
---|---|---|---|
options? | SiteUsersOptions | useSiteUsers hook options | Partially |
deps? | DependencyList | Hook dependency list. | Yes |
useSubWebInfos
useSubWebInfos(
options?: SubWebsOptions,
deps?: any[]): IWebInfosData[] | null | undefined;
Returns web info collection of current webs sub-webs.
Examples
Get all sub sites,
const subSites = useSubWebInfos();
Query sub sites,
const filteredSubSites = useSubWebInfos({
query: {
select: ["Title", "Id", "ServerRelativeUrl"],
filter: "WebTemplate eq 'STS'"
}
});
Parameters
Name | Type | Description | Tracked for changes |
---|---|---|---|
options? | SubWebsOptions | useSubWebs hook options | Partially |
deps? | DependencyList | Hook dependency list. | Yes |
useUser
useUser(
userId: string | number,
options?: UserOptions,
deps?: any[]): ISiteUserInfo | null | undefined;
Returns an user from site user collection.
Examples
Get site user by Id,
const userById = useUser(27);
Get site user by email,
const userByEmail = useUser("user@example.onmicrosoft.com");
Get site user by login name,
const userByLoginName = useUser("i:0#.f|membership|user@example.onmicrosoft.com");
Query site user properties,
const userById = useUser(27, {
query: {
select: ["Id", "Title", "LoginName"]
}
});
Parameters
Name | Type | Description | Tracked for changes |
---|---|---|---|
user | string | number | User Id, login name or email | Yes |
options? | UserOptions | useApps hook options | Partially |
deps? | DependencyList | Hook dependency list. | Yes |
useView
useView(
listId: string,
viewId?: string,
options?: ViewOptions,
deps?: any[]): IViewInfo | null | undefined;
Returns a list view.
Parameters
Name | Type | Description | Tracked for changes |
---|---|---|---|
listId? | string | List UUID or title | Yes |
viewId? | string | View UUID or title | Yes |
options? | ViewOptions | useView hook options | Partially |
deps? | DependencyList | Hook dependency list. | Yes |
Examples
Get default list view,
const defaultView = useView("My List Title");
Get list view by name,
const myView = useView("My List Title", "My View");
Get list view by UUID,
const myView = useView("My List Title", "9db07c1f-7880-4601-99d0-1c39c43f6599");
Query default list view properties,
const defaultViewInfo = useView("My List", undefined, {
query: {
select: ["Id"]
}
});
useViews
useViews(
listId: string,
options?: ViewsOptions,
deps?: any[]): IViewInfo[] | null | undefined;
Returns list view collection.
Examples
Get list views,
const allViews = useViews("9db07c1f-7880-4601-99d0-1c39c43f6599");
Query list views,
const viewTitles = useView("My List", {
query: {
select: ["Title"],
top: 5
}
});
Parameters
Name | Type | Description | Tracked for changes |
---|---|---|---|
listId | string | List UUID or title | Yes |
options? | ViewsOptions | useViews hook options | Partially |
deps? | DependencyList | Hook dependency list. | Yes |
useWebInfo
useWebInfo(
options?: WebInfoOptions,
deps?: any[]): IWebInfo | null | undefined;
Returns current web.
Examples
Get current web info,
const currentWeb = useWebInfo();
Query current web properties,
const currentWeb = useWebInfo({
query:{
select: ["Title"]
}
});
Parameters
Name | Type | Description | Tracked for changes |
---|---|---|---|
options? | WebInfoOptions | useWebInfo hook options | Partially |
deps? | DependencyList | Hook dependency list. | Yes |
useWebProperties
useWebProperties<T>(options?: WebPropertiesOptions, deps?: any[]): T | null | undefined;
Returns webs properties.
Examples
Get web properties,
const webPropertyBag = useWebProperties();
Parameters
Name | Type | Description | Tracked for changes |
---|---|---|---|
options? | WebPropertiesOptions | useWebProperties hook options | Partially |
deps? | DependencyList | Hook dependency list. | Yes |
Building & Testing
Building
pnpm install
pnpm run build
# or use npm
npm install
npm run build
Testing
Test system requires a SharePoint site and app registration on Microsoft identity platform with SharePoint permissions.
After the app registration, create a file named msalSettings.js
. You can use msalSettings.example.js
as a template or copy the following code snippet.
const privateKey = `
-----BEGIN RSA PRIVATE KEY-----
-----END RSA PRIVATE KEY-----`;
const msalInit = {
auth: {
authority: "https://login.microsoftonline.com/${TENANT_ID}",
clientId: "${CLIENT_ID}",
clientCertificate: {
thumbprint: "${THUMBPRINT}",
privateKey: privateKey,
},
}
};
export default
{
sp: {
url: "${SITE_URL}",
msal: {
init: msalInit,
scopes: ["${SITE_URL}/.default"]
},
},
graph: {
msal: {
init: msalInit,
scopes: ["https://graph.microsoft.com/.default"]
},
}
};
Replace the following parts in settings file with your own info from app registration:
privateKey
, replace it with your own certificate private key.${TENANT_ID}
, Your SharePoint tenant UUID.${CLIENT_ID}
, App client UUID.${SITE_URL}
, SharePoint test site URL.${THUMBPRINT}
, Certificate thumbprint.
Most tests use existing info on the site or create simple test cases on-the-fly. Only exceptions are useListItems
tests,
which require a list called Test List
with sizeable (+5000) pre-populated items.
Run npm run test
to start vitest
when testing environment is ready.
After the first test run, all HTTP responses are cached to
node_modules/.prh_cache
directory, and tests are replayed from the cached responses whenever there is a match.
CHANGELOG
v2.0.0 - The Wheelwright
Aug 04, 2024
Changed
- Minimum supported
@pnp/sp
peer dependency versions has been bumped to^4.1.0
. - The library now support React versions between
16.9.0
and^18.0.0
. useSearch
,useUserSearch
,useChanges
object queries are no longer automatically tracked internally. Instead, developers must use the custom dependency list for reactivity just like any other React hooks.- Migrated from TypeScript to JavaScript with JSDoc typings, but library still provides type definition files.
- Migrated from jest to vitest.
- All dependencies have been updated to their latest versions.
useSearch
and pageduseListItems
now provide data as argument on dispatch callbacks.- v1's Docusaurus repo has been archived, v2 docs are moved to the main repo.
- In
useListItems
paged mode, thehasNext
value is inverted to match with the async iteratorsdone
property.
Removed
useFolderTree
hook.- RxJs and tslib dependencies have been deleted.
v1.3.0
Apr 22, 2023
Added
- Site collection and tenant scope option for
useApp
anduseApps
hooks.
Changed
- Minimum supported
@pnp/sp
peer dependency version bumped to^3.14.0
v1.2.0
Dec 28, 2022
Added
useRecycleBinItem
anduseRecycleBinItems
hooks.createProviderElement
helper function for simplifiying SPFx initialization.
Fixed
useSearch
hook incorrectly overrides RowLimit whengetPageDispatch
is called.
v1.1.0
May 18, 2022
Added
useListItems
paged request option.useView
anduseViews
hooks.useListAsStream
hook.FetchWithAbort
behavior for cancelling fetch requests.
Fixed
useSearch
initiates double query issue.
v1.0.1
March 11, 2022
Fixed
useSearch
throwing error whengetPageDispatch
called more than one.
v1.0.0
March 09, 2022
Initial release