Fix issue that breaks the WooCommerce Home Page when Gutenberg 15.5 is active (#37641)

Co-authored-by: Ilyas Foo <foo.ilyas@gmail.com>
Co-authored-by: Chi-Hsuan Huang <chihsuan.tw@gmail.com>
Co-authored-by: rjchow <me@rjchow.com>
This commit is contained in:
Darren Ethier 2023-04-11 03:27:38 -04:00 committed by GitHub
parent 4cc6644c8b
commit 50593c5257
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 93 additions and 66 deletions

View File

@ -0,0 +1,4 @@
Significance: patch
Type: fix
Fix incorrect usage of dispatch, useSelect, and setState calls in homescreen along with settings and onboarding package

View File

@ -2,15 +2,14 @@
* External dependencies * External dependencies
*/ */
import { createHigherOrderComponent } from '@wordpress/compose'; import { createHigherOrderComponent } from '@wordpress/compose';
import { useSelect } from '@wordpress/data'; import { useDispatch, useSelect } from '@wordpress/data';
import { createElement, useRef } from '@wordpress/element'; import { createElement, useEffect, useRef } from '@wordpress/element';
/** /**
* Internal dependencies * Internal dependencies
*/ */
import { STORE_NAME } from './constants'; import { STORE_NAME } from './constants';
import { ProfileItems } from './types'; import { ProfileItems } from './types';
import { OnboardingSelector } from './';
export const withOnboardingHydration = ( data: { export const withOnboardingHydration = ( data: {
profileItems: ProfileItems; profileItems: ProfileItems;
@ -21,39 +20,54 @@ export const withOnboardingHydration = ( data: {
( OriginalComponent ) => ( props ) => { ( OriginalComponent ) => ( props ) => {
const onboardingRef = useRef( data ); const onboardingRef = useRef( data );
useSelect( const { isResolvingGroup, hasFinishedResolutionGroup } = useSelect(
// @ts-expect-error // @ts-expect-error registry is not defined in the wp.data typings ( select ) => {
( select: ( s: string ) => OnboardingSelector, registry ) => {
if ( ! onboardingRef.current ) {
return;
}
const { isResolving, hasFinishedResolution } = const { isResolving, hasFinishedResolution } =
select( STORE_NAME ); select( STORE_NAME );
const { return {
startResolution, isResolvingGroup: isResolving( 'getProfileItems', [] ),
finishResolution, hasFinishedResolutionGroup: hasFinishedResolution(
setProfileItems, 'getProfileItems',
} = registry.dispatch( STORE_NAME ); []
),
const { profileItems } = onboardingRef.current; };
}
if (
profileItems &&
! hydratedProfileItems &&
! isResolving( 'getProfileItems', [] ) &&
! hasFinishedResolution( 'getProfileItems', [] )
) {
startResolution( 'getProfileItems', [] );
setProfileItems( profileItems, true );
finishResolution( 'getProfileItems', [] );
hydratedProfileItems = true;
}
},
[]
); );
const { startResolution, finishResolution, setProfileItems } =
useDispatch( STORE_NAME );
useEffect( () => {
if ( ! onboardingRef.current ) {
return;
}
const { profileItems } = onboardingRef.current;
if ( ! profileItems ) {
return;
}
if (
profileItems &&
! hydratedProfileItems &&
// Ensure that profile items have finished resolving to prevent race conditions
! isResolvingGroup &&
! hasFinishedResolutionGroup
) {
startResolution( 'getProfileItems', [] );
setProfileItems( profileItems, true );
finishResolution( 'getProfileItems', [] );
hydratedProfileItems = true;
}
}, [
finishResolution,
setProfileItems,
startResolution,
isResolvingGroup,
hasFinishedResolutionGroup,
] );
return <OriginalComponent { ...props } />; return <OriginalComponent { ...props } />;
}, },
'withOnboardingHydration' 'withOnboardingHydration'

View File

@ -10,7 +10,7 @@ import { SelectFromMap, DispatchFromMap } from '@automattic/data-stores';
/** /**
* Internal dependencies * Internal dependencies
*/ */
import { WPDataSelectors } from '../types'; import { WPDataSelectors, WPDataActions } from '../types';
import { STORE_NAME } from './constants'; import { STORE_NAME } from './constants';
import * as selectors from './selectors'; import * as selectors from './selectors';
import * as actions from './actions'; import * as actions from './actions';
@ -33,7 +33,7 @@ export const SETTINGS_STORE_NAME = STORE_NAME;
declare module '@wordpress/data' { declare module '@wordpress/data' {
function dispatch( function dispatch(
key: typeof STORE_NAME key: typeof STORE_NAME
): DispatchFromMap< typeof actions >; ): DispatchFromMap< typeof actions > & WPDataActions;
function select( function select(
key: typeof STORE_NAME key: typeof STORE_NAME
): SelectFromMap< typeof selectors > & WPDataSelectors; ): SelectFromMap< typeof selectors > & WPDataSelectors;

View File

@ -2,8 +2,8 @@
* External dependencies * External dependencies
*/ */
import { createHigherOrderComponent } from '@wordpress/compose'; import { createHigherOrderComponent } from '@wordpress/compose';
import { useSelect, select as wpSelect } from '@wordpress/data'; import { useDispatch, useSelect } from '@wordpress/data';
import { createElement, useRef } from '@wordpress/element'; import { createElement, useRef, useEffect } from '@wordpress/element';
/** /**
* Internal dependencies * Internal dependencies
@ -16,31 +16,46 @@ export const withSettingsHydration = ( group: string, settings: Settings ) =>
( OriginalComponent ) => ( props ) => { ( OriginalComponent ) => ( props ) => {
const settingsRef = useRef( settings ); const settingsRef = useRef( settings );
// @ts-expect-error registry is not defined in the wp.data typings const {
useSelect( ( select: typeof wpSelect, registry ) => { startResolution,
finishResolution,
updateSettingsForGroup,
clearIsDirty,
} = useDispatch( STORE_NAME );
const { isResolvingGroup, hasFinishedResolutionGroup } = useSelect(
( select ) => {
const { isResolving, hasFinishedResolution } =
select( STORE_NAME );
return {
isResolvingGroup: isResolving( 'getSettings', [
group,
] ),
hasFinishedResolutionGroup: hasFinishedResolution(
'getSettings',
[ group ]
),
};
},
[]
);
useEffect( () => {
if ( ! settingsRef.current ) { if ( ! settingsRef.current ) {
return; return;
} }
if ( ! isResolvingGroup && ! hasFinishedResolutionGroup ) {
const { isResolving, hasFinishedResolution } =
select( STORE_NAME );
const {
startResolution,
finishResolution,
updateSettingsForGroup,
clearIsDirty,
} = registry.dispatch( STORE_NAME );
if (
! isResolving( 'getSettings', [ group ] ) &&
! hasFinishedResolution( 'getSettings', [ group ] )
) {
startResolution( 'getSettings', [ group ] ); startResolution( 'getSettings', [ group ] );
updateSettingsForGroup( group, settingsRef.current ); updateSettingsForGroup( group, settingsRef.current );
clearIsDirty( group ); clearIsDirty( group );
finishResolution( 'getSettings', [ group ] ); finishResolution( 'getSettings', [ group ] );
} }
}, [] ); }, [
isResolvingGroup,
hasFinishedResolutionGroup,
finishResolution,
updateSettingsForGroup,
startResolution,
clearIsDirty,
] );
return <OriginalComponent { ...props } />; return <OriginalComponent { ...props } />;
}, },

View File

@ -3,7 +3,6 @@
*/ */
import { compose } from '@wordpress/compose'; import { compose } from '@wordpress/compose';
import { withSelect } from '@wordpress/data'; import { withSelect } from '@wordpress/data';
import { identity } from 'lodash';
import { import {
ONBOARDING_STORE_NAME, ONBOARDING_STORE_NAME,
withOnboardingHydration, withOnboardingHydration,
@ -50,10 +49,8 @@ const withSelectHandler = ( select: WCDataSelector ) => {
}; };
export default compose( export default compose(
onboardingData.profile withOnboardingHydration( {
? withOnboardingHydration( { profileItems: onboardingData.profile,
profileItems: onboardingData.profile, } ),
} )
: identity,
withSelect( withSelectHandler ) withSelect( withSelectHandler )
)( Homescreen ); )( Homescreen );

View File

@ -7,7 +7,6 @@ import {
useCallback, useCallback,
useLayoutEffect, useLayoutEffect,
useRef, useRef,
useState,
} from '@wordpress/element'; } from '@wordpress/element';
import { compose } from '@wordpress/compose'; import { compose } from '@wordpress/compose';
import { withDispatch, withSelect } from '@wordpress/data'; import { withDispatch, withSelect } from '@wordpress/data';
@ -53,7 +52,6 @@ const Tasks = lazy( () =>
export const Layout = ( { export const Layout = ( {
defaultHomescreenLayout, defaultHomescreenLayout,
isBatchUpdating,
query, query,
taskListComplete, taskListComplete,
hasTaskList, hasTaskList,
@ -68,7 +66,6 @@ export const Layout = ( {
const shouldShowStoreLinks = taskListComplete || isTaskListHidden; const shouldShowStoreLinks = taskListComplete || isTaskListHidden;
const hasTwoColumnContent = const hasTwoColumnContent =
shouldShowStoreLinks || window.wcAdminFeatures.analytics; shouldShowStoreLinks || window.wcAdminFeatures.analytics;
const [ showInbox, setShowInbox ] = useState( true );
const isDashboardShown = ! query.task; // ?&task=<x> query param is used to show tasks instead of the homescreen const isDashboardShown = ! query.task; // ?&task=<x> query param is used to show tasks instead of the homescreen
const activeSetupTaskList = useActiveSetupTasklist(); const activeSetupTaskList = useActiveSetupTasklist();
@ -76,10 +73,6 @@ export const Layout = ( {
( userPrefs.homepage_layout || defaultHomescreenLayout ) === ( userPrefs.homepage_layout || defaultHomescreenLayout ) ===
'two_columns' && hasTwoColumnContent; 'two_columns' && hasTwoColumnContent;
if ( isBatchUpdating && ! showInbox ) {
setShowInbox( true );
}
const isWideViewport = useRef( true ); const isWideViewport = useRef( true );
const maybeToggleColumns = useCallback( () => { const maybeToggleColumns = useCallback( () => {
isWideViewport.current = window.innerWidth >= 782; isWideViewport.current = window.innerWidth >= 782;

View File

@ -0,0 +1,4 @@
Significance: patch
Type: fix
Fix incorrect usage of dispatch, useSelect, and setState calls in homescreen along with settings and onboarding package