What SharePoint development model, framework, SDK or API is this about?
💥 SharePoint Framework
Developer environment
Windows
What browser(s) / client(s) have you tested
[ ] 💥 Internet Explorer
[ ] 💥 Microsoft Edge
[X] 💥 Google Chrome
[ ] 💥 FireFox
[ ] 💥 Safari
[ ] mobile (iOS/iPadOS)
[ ] mobile (Android)
[ ] not applicable
[ ] other (enter in the "Additional environment details" area below)
Additional environment details
browser version: Chrome 130.0.6723.59
SPFx version: 1.20.0
Node.js version: v18.20.4
Describe the bug / error
We are experiencing an issue similar to #9640, in which we have a Command Set button that renders a Panel component using ReactDOM.render(...) when clicked. Occasionally this errors and the console has the #321 React error.
The issue is not specific to the Panel component. Fully removing the Fluent UI React package and rendering a component that outputs a plain div which also uses hooks e.g. useEffect will get the same intermittent error.
After a page refresh, it works again.
The intermittent nature makes this difficult to fully confirm, but these are the current findings:
If the rendered component(s) don't use hooks, it works ok
If we drop the React version to 16.13.1, it works ok
If we drop the SPFx version e.g. down to 1.18.0, it still errors when using React 17
Example code:
Command Set configured to attached to Lists and Libraries
import {
BaseListViewCommandSet,
type Command,
type IListViewCommandSetExecuteEventParameters,
} from "@microsoft/sp-listview-extensibility";
import * as React from "react";
import * as ReactDOM from "react-dom";
import CommandPanel from "./components/CommandPanel";
export default class ArchiveCommandSet extends BaseListViewCommandSet<IArchiveCommandSetProperties> {
private _panelPlaceHolder: HTMLDivElement;
public onInit(): Promise<void> {
this._panelPlaceHolder = document.body.appendChild(
document.createElement("div")
);
const archiveCommand: Command = this.tryGetCommand("COMMAND_ARCHIVE");
archiveCommand.visible = true;
return Promise.resolve();
}
public onExecute(event: IListViewCommandSetExecuteEventParameters): void {
switch (event.itemId) {
case "COMMAND_ARCHIVE":
this._renderPanelComponent();
break;
default:
throw new Error("Unknown command");
}
}
public onDispose(): void {
ReactDOM.unmountComponentAtNode(this._panelPlaceHolder);
}
private _renderPanelComponent = (): void => {
const element: React.ReactElement = React.createElement(CommandPanel);
ReactDOM.render(element, this._panelPlaceHolder);
};
}
From what we can determine, it happens (intermittently) with the following steps:
Open a fresh browser session
Navigate to the SharePoint library
Refresh the page (this seems to be the key step)
Click the Command Set button
Sometimes results in the React 321 error
From our testing, it seems to be the refresh step which then results in the behaviour happening. Without the refresh, we've not been able to reproduce it - but as it's intermittent, that's hard to say for certain!
However...when in the failed state, a page refresh then resolves it.
Expected behavior
For the component rendered via ReactDOM.render(...) to work consistently.
Target SharePoint environment
SharePoint Online
What SharePoint development model, framework, SDK or API is this about?
💥 SharePoint Framework
Developer environment
Windows
What browser(s) / client(s) have you tested
Additional environment details
Describe the bug / error
We are experiencing an issue similar to #9640, in which we have a Command Set button that renders a Panel component using
ReactDOM.render(...)
when clicked. Occasionally this errors and the console has the #321 React error.The issue is not specific to the Panel component. Fully removing the Fluent UI React package and rendering a component that outputs a plain
div
which also uses hooks e.g.useEffect
will get the same intermittent error.After a page refresh, it works again.
The intermittent nature makes this difficult to fully confirm, but these are the current findings:
Example code:
Command Set configured to attached to Lists and Libraries
Failing Component:
package.json
Steps to reproduce
From what we can determine, it happens (intermittently) with the following steps:
From our testing, it seems to be the refresh step which then results in the behaviour happening. Without the refresh, we've not been able to reproduce it - but as it's intermittent, that's hard to say for certain!
However...when in the failed state, a page refresh then resolves it.
Expected behavior
For the component rendered via
ReactDOM.render(...)
to work consistently.