SPFx DynamicForm Control with PnP React Controls
The DynamicForm control from the PnP SPFx React Controls library is one of the most powerful components available for SharePoint Framework development. Instead of manually creating React forms, field validation, save logic, lookup controls, taxonomy controls, people pickers, and attachments handling, DynamicForm automatically generates a form based on the structure of a SharePoint list.
This dramatically reduces development time and ensures that the user experience remains consistent with SharePoint Online. The control reads the list metadata, renders the appropriate fields, performs validation, and handles item creation or editing.
Official documentation:
Why Use DynamicForm?
Traditional SPFx forms usually require:
- React state management
- SharePoint REST or Graph calls
- Validation logic
- Save and update operations
- Field rendering
- Lookup field handling
- Taxonomy support
- Person or Group selection
The DynamicForm control automatically handles most of these tasks.
Benefits include:
- Rapid development
- Reduced code
- Automatic SharePoint field rendering
- Built-in validation
- Create and Edit support
- Consistent SharePoint user experience
- Support for complex SharePoint column types
Installing the Library
npm install @pnp/spfx-controls-react --save
Example Scenario
In this example the form edits item ID 1 from the SharePoint list:
ab7a0321-e395-40c5-89d5-fad2b68fc6cd
The control automatically loads the item and displays all editable fields.
Complete React Component
import * as React from 'react';import { DynamicForm } from "@pnp/spfx-controls-react/lib/DynamicForm";interface IDynamicFormExProps { context: any;}const DynamicFormEx: React.FC<IDynamicFormExProps> = ({ context }) => { return ( <DynamicForm context={context} listId={"ab7a0321-e395-40c5-89d5-fad2b68fc6cd"} listItemId={1} onCancelled={() => { console.log('Cancelled'); }} onBeforeSubmit={async (listItem) => { return false; }} onSubmitError={(listItem, error) => { alert(error.message); }} onSubmitted={async (listItemData) => { console.log(listItemData); }} /> );};export default DynamicFormEx;
Understanding Each Property
context
context={context}
Provides the SPFx context required by the control to communicate with SharePoint.
listId
listId={"ab7a0321-e395-40c5-89d5-fad2b68fc6cd"}
Identifies the SharePoint list.
You can obtain this value from:
List Settings → List ID
Example:
ab7a0321-e395-40c5-89d5-fad2b68fc6cd
listItemId
listItemId={1}
Specifies the SharePoint item to edit.
Example:
Item ID = 1
When omitted, the control can be used to create a new item.
Event: onCancelled
onCancelled={() => { console.log('Cancelled');}}
Triggered when the user clicks Cancel.
Typical uses:
- Close dialogs
- Redirect users
- Show notifications
Example:
onCancelled={() => { alert('Operation cancelled');}}
Event: onBeforeSubmit
onBeforeSubmit={async (listItem) => { return false;}}
Executed before saving.
This event allows custom validation.
Example:
onBeforeSubmit={async (listItem) => { if (!listItem.Title) { alert('Title is required'); return true; } return false;}}
Common use cases:
- Business rules
- Required field validation
- Duplicate checking
- Data transformations
Event: onSubmitError
onSubmitError={(listItem, error) => { alert(error.message);}}
Triggered when SharePoint returns an error.
Example errors:
- Permission denied
- Required field missing
- Invalid lookup value
- Validation failure
Example:
onSubmitError={(listItem, error) => { console.error(error); alert( `Error saving item: ${error.message}` );}}
Event: onSubmitted
onSubmitted={async (listItemData) => { console.log(listItemData);}}
Executed after successful save.
Typical uses:
- Refresh data
- Show confirmation messages
- Redirect users
- Close dialogs
Example:
onSubmitted={async (listItemData) => { alert('Item saved successfully'); console.log(listItemData);}}
Creating New Items
To create a new item, simply remove the item identifier:
<DynamicForm context={context} listId={"ab7a0321-e395-40c5-89d5-fad2b68fc6cd"}/>
The form automatically switches to Create mode.
Editing Existing Items
<DynamicForm context={context} listId={"ab7a0321-e395-40c5-89d5-fad2b68fc6cd"} listItemId={1}/>
The control loads existing values and switches to Edit mode.
SharePoint Columns Supported
DynamicForm automatically renders many SharePoint field types:
| SharePoint Field Type | Supported |
|---|---|
| Single Line of Text | Yes |
| Multiple Lines of Text | Yes |
| Number | Yes |
| Currency | Yes |
| Date and Time | Yes |
| Choice | Yes |
| Multi Choice | Yes |
| Yes/No | Yes |
| Lookup | Yes |
| Person or Group | Yes |
| Managed Metadata | Yes |
| Hyperlink | Yes |
| Attachments | Yes |
When to Use DynamicForm
DynamicForm is an excellent choice when:
- Building CRUD applications
- Creating administrative tools
- Developing list management solutions
- Creating approval forms
- Replacing SharePoint classic forms
- Rapid prototyping SPFx solutions
For highly customized layouts and complex UI requirements, a fully custom React form may still be preferable.
Conclusion
The DynamicForm control is one of the most productive controls available in the PnP SPFx React Controls library. It allows developers to generate SharePoint forms dynamically from list metadata, significantly reducing the amount of React and SharePoint code required while maintaining a modern and consistent user experience.
By simply providing the SPFx context, a List ID, and optionally an Item ID, developers can create complete SharePoint Create/Edit forms with validation, field rendering, and save operations already implemented.
Official Documentation
PnP Controls Roadmap Progress
| WP | Control | Status |
|---|---|---|
| WP01 | AccessibleAccordion | ✅ |
| WP02 | Accordion | ✅ |
| WP03 | AdaptiveCardHost | ✅ |
| WP04 | AnimatedDialog | ✅ |
| WP05 | Carousel | ✅ |
| WP06 | ChartControl | ✅ |
| WP07 | Dashboard | ✅ |
| WP08 | DragDropFiles | ✅ |
| WP49 | DynamicForm | ✅ |
