Rewrite the withPluginsHydration hook to not dispatch inside useSelect (#37896)

* Fix types to allow startResolutions etc actions

* Rewrite the usePluginsHydration hook to not dispatch inside useSelect

* Add changelog

* Remove unused import
This commit is contained in:
Moon 2023-04-20 20:09:00 -07:00 committed by GitHub
parent 85a71f8cee
commit 83981c61b2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 40 additions and 48 deletions

View File

@ -0,0 +1,4 @@
Significance: patch
Type: dev
Rewrite usePluginsHydration hook to not dispatch inside useSelect

View File

@ -12,7 +12,7 @@ import * as selectors from './selectors';
import * as actions from './actions';
import * as resolvers from './resolvers';
import reducer, { State } from './reducer';
import { WPDataSelectors } from '../types';
import { WPDataActions, WPDataSelectors } from '../types';
export * from './types';
export type { State };
@ -29,7 +29,7 @@ declare module '@wordpress/data' {
// TODO: convert action.js to TS
function dispatch(
key: typeof STORE_NAME
): DispatchFromMap< typeof actions >;
): DispatchFromMap< typeof actions & WPDataActions >;
function select(
key: typeof STORE_NAME
): SelectFromMap< typeof selectors > & WPDataSelectors;

View File

@ -3,16 +3,14 @@
*/
import { createHigherOrderComponent } from '@wordpress/compose';
import { useSelect } from '@wordpress/data';
import { createElement, useRef } from '@wordpress/element';
import { useSelect, useDispatch } from '@wordpress/data';
import { createElement, useEffect } from '@wordpress/element';
import { SelectFromMap } from '@automattic/data-stores';
/**
* Internal dependencies
*/
import { STORE_NAME } from './constants';
import { WPDataActions } from '../';
import * as actions from './actions';
import * as selectors from './selectors';
import { WPDataSelectors } from '../types';
@ -24,63 +22,53 @@ type PluginHydrationData = {
export const withPluginsHydration = ( data: PluginHydrationData ) =>
createHigherOrderComponent< Record< string, unknown > >(
( OriginalComponent ) => ( props ) => {
const dataRef = useRef( data );
useSelect(
// @ts-expect-error registry is not defined in the wp.data typings
const shouldHydrate = useSelect(
(
select: (
key: typeof STORE_NAME
) => SelectFromMap< typeof selectors > & WPDataSelectors,
registry: {
dispatch: (
store: string
) => typeof actions & WPDataActions;
}
) => SelectFromMap< typeof selectors > & WPDataSelectors
) => {
if ( ! dataRef.current ) {
if ( ! data ) {
return;
}
const { isResolving, hasFinishedResolution } =
select( STORE_NAME );
const {
startResolution,
finishResolution,
updateActivePlugins,
updateInstalledPlugins,
updateIsJetpackConnected,
} = registry.dispatch( STORE_NAME );
if (
return (
! isResolving( 'getActivePlugins', [] ) &&
! hasFinishedResolution( 'getActivePlugins', [] )
) {
startResolution( 'getActivePlugins', [] );
startResolution( 'getInstalledPlugins', [] );
startResolution( 'isJetpackConnected', [] );
updateActivePlugins(
dataRef.current.activePlugins,
true
);
updateInstalledPlugins(
dataRef.current.installedPlugins,
true
);
updateIsJetpackConnected(
dataRef.current.jetpackStatus &&
dataRef.current.jetpackStatus.isActive
? true
: false
);
finishResolution( 'getActivePlugins', [] );
finishResolution( 'getInstalledPlugins', [] );
finishResolution( 'isJetpackConnected', [] );
}
);
},
[]
);
const {
startResolution,
finishResolution,
updateActivePlugins,
updateInstalledPlugins,
updateIsJetpackConnected,
} = useDispatch( STORE_NAME );
useEffect( () => {
if ( ! shouldHydrate ) {
return;
}
startResolution( 'getActivePlugins', [] );
startResolution( 'getInstalledPlugins', [] );
startResolution( 'isJetpackConnected', [] );
updateActivePlugins( data.activePlugins, true );
updateInstalledPlugins( data.installedPlugins, true );
updateIsJetpackConnected(
data.jetpackStatus && data.jetpackStatus.isActive
? true
: false
);
finishResolution( 'getActivePlugins', [] );
finishResolution( 'getInstalledPlugins', [] );
finishResolution( 'isJetpackConnected', [] );
}, [ shouldHydrate ] );
return <OriginalComponent { ...props } />;
},
'withPluginsHydration'