Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Serializer: Fix Invariant error related to hooks #15873

Closed
wants to merge 1 commit into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
26 changes: 24 additions & 2 deletions packages/element/src/serialize.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,9 @@ import {
startsWith,
kebabCase,
isPlainObject,
noop,
} from 'lodash';
import { __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED } from 'react';
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

😅

Copy link
Contributor Author

@nerrad nerrad Jun 9, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

moderator note there was some spam commenting on this issue. I reported the user to github and blocked them from this repo


/**
* WordPress dependencies
Expand All @@ -54,6 +56,20 @@ import RawHTML from './raw-html';

const { Provider, Consumer } = createContext();

const Dispatcher = {
readContext: noop,
useContext: noop,
useMemo: noop,
useReducer: () => [],
useRef: () => ( { current: '' } ),
useState: () => [],
useLayoutEffect: noop,
useCallback: noop,
useImperativeHandle: noop,
useEffect: noop,
useDebugValue: noop,
};

Copy link
Contributor Author

@nerrad nerrad May 29, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was mostly just to get the ball rolling on one option which is monkey patching the ReactCurrentDispatcher before doing the render. However, if we go this route, we'll probably have to reproduce similar logic for hooks found here. This seems fragile and increases maintenance burden. The other (maybe not significant) potential issue is that essentially any logic in a useEffect or useLayoutEffect hook in a rendered component will not fire if we use something similar to ReactPartialRendererHooks because this serializer is effectively doing similar to what server type tasks do (as opposed to browser).

If renderToString is mostly used for the save function of blocks (stateless components) I wonder if we should simply detect usages of withSelect/hooks and simply NOT support them (throw errors?).

/**
* Valid attribute types.
*
Expand Down Expand Up @@ -396,8 +412,14 @@ export function renderElement( element, context, legacyContext = {} ) {
if ( type.prototype && typeof type.prototype.render === 'function' ) {
return renderComponent( type, props, context, legacyContext );
}

return renderElement( type( props, legacyContext ), context, legacyContext );
const prevDispatcher = __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentDispatcher;
__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentDispatcher.current = Dispatcher;
const value = renderElement( type( props, legacyContext ),
context,
legacyContext
);
__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentDispatcher = prevDispatcher;
return value;
}

switch ( type && type.$$typeof ) {
Expand Down