-
Notifications
You must be signed in to change notification settings - Fork 1k
Description
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
- 💥 Internet Explorer
- 💥 Microsoft Edge
- 💥 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);
};
}
Failing Component:
import * as React from "react";
const CommandPanel: React.FunctionComponent = () => {
React.useEffect(() => { console.log("hello"); }, []);
return (
<div
style={{
position: "absolute",
top: "20%",
left: "40%",
backgroundColor: "red",
fontSize: "18px",
padding: "2em 1em",
zIndex: 99999,
}}
>
hello world!
</div>
);
};
export default CommandPanel;
package.json
{
"name": "test",
"version": "0.0.1",
"private": true,
"engines": {
"node": ">=18.17.1 <19.0.0"
},
"main": "lib/index.js",
"scripts": {
"build": "gulp bundle",
"clean": "gulp clean",
"test": "gulp test"
},
"dependencies": {
"@microsoft/decorators": "1.20.0",
"@microsoft/sp-core-library": "1.20.0",
"@microsoft/sp-dialog": "1.20.0",
"@microsoft/sp-listview-extensibility": "1.20.0",
"@microsoft/sp-lodash-subset": "1.20.0",
"@microsoft/sp-office-ui-fabric-core": "1.20.0",
"@microsoft/sp-property-pane": "1.20.0",
"@microsoft/sp-webpart-base": "1.20.0",
"react": "17.0.1",
"react-dom": "17.0.1",
"tslib": "2.3.1"
},
"devDependencies": {
"@microsoft/eslint-config-spfx": "1.20.2",
"@microsoft/eslint-plugin-spfx": "1.20.2",
"@microsoft/rush-stack-compiler-4.7": "0.1.0",
"@microsoft/sp-build-web": "1.20.2",
"@microsoft/sp-module-interfaces": "1.20.2",
"@rushstack/eslint-config": "4.0.1",
"@types/webpack-env": "~1.15.2",
"ajv": "^6.12.5",
"eslint": "8.57.0",
"gulp": "4.0.2",
"typescript": "4.7.4"
}
}
Steps to reproduce
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.
