Reputation: 29
I have a written a class component in SPFx with the pnp/js framework and React.js. I need to transform it to a functional component in react. I'm struggeling to call my SharePoint lists now. I have a SharePoint DataProvider.ts and a pnpConfig.ts
Here ist my code so far: SharePoint DataProvider.ts
import {getSP} from '../PNPConfig/pnpConfig';
import {SPFI} from "@pnp/sp";
import { WebPartContext } from '@microsoft/sp-webpart-base';
import { IMedEvalListItem } from
'../spFxReactFuncFragebogen/components/IMedEvalListItemDefinition';}
export default class SharePointDataProvider{
private _sp: SPFI;
constructor(wpContext: WebPartContext){
this._sp=getSP(wpContext);
}
public GetSPObject(): SPFI {
return this._sp;
}
public GetLists = async (): Promise<IMedEvalListItem[]> => {
try{
const response: IMedEvalListItem[] =await
this._sp.web.lists.select("Title","Id").filter("Hidden eq false")();
return response;
}
catch(e){
return e;
}
}
}
PNP Config:
import { WebPartContext } from "@microsoft/sp-webpart-base";
import {spfi, SPFI, SPFx} from "@pnp/sp";
import {LogLevel, PnPLogging} from "@pnp/logging";
import "@pnp/sp/webs";
import "@pnp/sp/lists";
import "@pnp/sp/items";
import "@pnp/sp/batching";
export const getSP= (context:WebPartContext): SPFI =>{
return spfi().using(SPFx(context as
WebPartContext)).using(PnPLogging(LogLevel.Warning));
};
My function component:
import * as React from 'react';
//import styles from './SpFxReactFuncFragebogen.module.scss';
import type { ISpFxReactFuncFragebogenProps } from './ISpFxReactFuncFragebogenProps';
import { IMedEvalListItem } from './IMedEvalListItemDefinition';
import SharePointDataProvider from '../../DataProvider/SharePointDataProvider';
export default function
SpFxReactFuncFragebogen(props:ISpFxReactFuncFragebogenProps):React.ReactElement<ISpFxReactFuncFragebogenProps> {
const[medItems,setMedItems]=React.useState<[IMedEvalListItem]>();
const spService= new SharePointDataProvider(this.context);
React.useEffect(() => {
fetchListItems();
}, []);
const fetchListItems = async () => {
try {
const items = await spService.GetLists();
setMedItems(items);
} catch (error) {
console.error('Error fetching list items:', error);
}
};
return (
<section>
<div>
{medItems}
</div>
</section>
);
}
I'm not sure where my errors are. I need to know if I can call SharePoint like this and how I get the values in the useState Variable.
Best regards
Matthias
Upvotes: 1
Views: 304
Reputation: 6859
Take a look at this blog post that shows how to convert a SPFx class component into a functional component. It includes an example of getting data from SharePoint using the REST API and render it in the web part.
How to use React Hooks with the SharePoint Framework (SPFx)
import * as React from 'react';
import { useState } from 'react';
import { useState, useEffect } from 'react';
import styles from './SpFxReactHooks.module.scss';
import { ISpFxReactHooksProps } from './ISpFxReactHooksProps';
import { escape } from '@microsoft/sp-lodash-subset';
import { SPHttpClient, SPHttpClientResponse } from '@microsoft/sp-http';
const SpFxReactHooks: React.FC<ISpFxReactHooksProps> = (props) => {
const {
hasTeamsContext,
userDisplayName,
// update prop interface & add as input prop in web part (not shown)
spHttpClient
} = props;
const [counter, setCounter] = useState<number>(1);
const [evenOdd, setEvenOdd] = useState<string>('');
const [siteLists, setSiteLists] = useState<string[]>([]);
useEffect(() => {
(async () => {
// line wrapping added for readability
const endpoint: string = `${currentSiteUrl}/_api/web/lists
?$select=Title
&$filter=Hidden eq false
&$orderby=Title
&$top=10`;
const rawResponse: SPHttpClientResponse = await spHttpClient.get(
endpoint, SPHttpClient.configurations.v1);
setSiteLists(
(await rawResponse.json()).value.map((list: { Title: string }) => {
return list.Title;
})
);
})();
}, []);
useEffect(() => {
setEvenOdd((counter % 2 === 0) ? 'even' : 'odd');
}, [counter]);
const onButtonClick = (): void => {
setCounter(counter + 1);
}
return (
<section className={`${styles.SpFxReactHooks} ${hasTeamsContext ? styles.teams : ''}`}>
<div className={styles.welcome}>
<h2>Well done, {escape(userDisplayName)}!</h2>
<div>Counter: <strong>{counter}</strong> is <strong>{evenOdd}</strong></div>
<button onClick={() => onButtonClick()}>+</button>
<ul>
{
siteLists.map((list: string) => (
<li>{list}</li>
))
}
</ul>
</div>
</section>
);
}
export default SpFxReactHooks;
Upvotes: 0