Bug: TypeError: d is not a constructor
-
Hello,
Thank you for maintaining Widget Options. I would like to report a compatibility bug with the Gutenberg Page & Post Block Options module, and request a fix.
Environment
- Widget Options version: 4.2.5
- WordPress: 7.0.4
- Gutenberg / Block Editor (core)
What happens
When Gutenberg Page & Post Block Options is enabled:
- Open the block editor on a page/post.
- Insert or open a custom block whose registered
editcomponent is wrapped withReact.memo(or another non-callable React element type such asforwardRef/lazy). - The block fails to mount and shows:
“This block has encountered an error and cannot be previewed.” - Browser console error (minified variable name may differ):
TypeError: d is not a constructor
at the filter registered onblocks.registerBlockTypeinincludes/widgets/gutenberg/build/index.js
(namespace:extended-widget-options/sidebar-component), inside thetry/catchthat ends withreturn new d(e).
Core blocks such as Paragraph work normally.
The issue only appears for blocks whose registerededitis not a plain function/class (for example,memo-wrapped components).Disabling Gutenberg Page & Post Block Options resolves the error immediately.
Root cause
In
includes/widgets/gutenberg/build/index.js, the plugin adds ablocks.registerBlockTypefilter that wraps every block’seditroughly like this:const d = settings.edit;
settings.edit = function ( props ) {
// ... initialize extended_widget_opts_* attributes ...
try {
return d( props ); // call as a function
} catch ( err ) {
return new d( props ); // fallback: treat as a class constructor
}
};This is not how React components should be rendered.
- Gutenberg normally renders
editviawp.element.createElement( OriginalEdit, props ). - Calling
OriginalEdit(props)only works for plain function components. new OriginalEdit(props)only works for class components.- Components created with
React.memo(),forwardRef(),lazy(), etc. are objects, not callable functions and not constructors. For those:d(props)throws (e.g. “is not a function”)new d(props)throwsTypeError: d is not a constructor← the error we see
That is why core blocks (plain function
edit) still work, while many modern third-party blocks break.This is independent of any specific Lazy Edit / code-splitting feature in other plugins: any block that registers a memoized
editis affected.Requested fix
Please change the wrapper so it always renders the original
editwithcreateElement(or equivalent), for example:const OriginalEdit = settings.edit;
settings.edit = function ( props ) {
// … your attribute initialization …
return wp.element.createElement( OriginalEdit, props );
};There is no need for the
try { OriginalEdit(props) } catch { new OriginalEdit(props) }pattern.Expected result
With Gutenberg Page & Post Block Options enabled, third-party blocks that use
React.memo(and similar) foreditshould mount normally, the same as core blocks.I would appreciate it if you could confirm and ship a fix in an upcoming release. Happy to provide more details or test a patch if helpful.
Thank you.
You must be logged in to reply to this topic.