Make use of memoization to prevent DynamicForm re-initialization (https://github.com/woocommerce/woocommerce-admin/pull/7256)

* Make use of memoization to prevent DynamicForm re-initialization

* Use rendered element for defaultForm to keep component reference

* Fix formatting
This commit is contained in:
louwie17 2021-06-29 17:06:31 -03:00 committed by GitHub
parent 7e20ebf866
commit ee791957ce
4 changed files with 43 additions and 38 deletions

View File

@ -100,14 +100,13 @@ export const Configure = ( {
const helpText = setupHelpText && (
<p dangerouslySetInnerHTML={ sanitizeHTML( setupHelpText ) } />
);
const DefaultForm = ( props ) => (
const defaultForm = (
<DynamicForm
fields={ fields }
isBusy={ isUpdating }
onSubmit={ handleSubmit }
submitLabel={ __( 'Proceed', 'woocommerce-admin' ) }
validate={ ( values ) => validateFields( values, fields ) }
{ ...props }
/>
);
@ -115,7 +114,7 @@ export const Configure = ( {
return (
<WooPaymentGatewayConfigure.Slot
fillProps={ {
defaultForm: DefaultForm,
defaultForm,
defaultSubmit: handleSubmit,
defaultFields: fields,
markConfigured: () => markConfigured( id ),
@ -141,7 +140,7 @@ export const Configure = ( {
return (
<>
{ helpText }
<DefaultForm />
{ defaultForm }
</>
);
}

View File

@ -13,7 +13,7 @@ import {
import { Plugins, Stepper } from '@woocommerce/components';
import { WooPaymentGatewaySetup } from '@woocommerce/onboarding';
import { recordEvent } from '@woocommerce/tracks';
import { useEffect, useState, useMemo, useCallback } from '@wordpress/element';
import { useEffect, useState, useMemo } from '@wordpress/element';
import { useSelect, useDispatch } from '@wordpress/data';
import { useSlot } from '@woocommerce/experimental';
@ -151,17 +151,13 @@ export const Setup = ( {
isPaymentGatewayResolving ||
! isPluginLoaded;
const DefaultStepper = useCallback(
( props ) => (
<Stepper
isVertical
isPending={ stepperPending }
currentStep={ needsPluginInstall ? 'install' : 'configure' }
steps={ [ installStep, configureStep ].filter( Boolean ) }
{ ...props }
/>
),
[ stepperPending, installStep, configureStep ]
const defaultStepper = (
<Stepper
isVertical
isPending={ stepperPending }
currentStep={ needsPluginInstall ? 'install' : 'configure' }
steps={ [ installStep, configureStep ].filter( Boolean ) }
/>
);
return (
@ -170,7 +166,7 @@ export const Setup = ( {
{ hasFills ? (
<WooPaymentGatewaySetup.Slot
fillProps={ {
defaultStepper: DefaultStepper,
defaultStepper,
defaultInstallStep: installStep,
defaultConfigureStep: configureStep,
markConfigured: () => markConfigured( id ),
@ -179,7 +175,7 @@ export const Setup = ( {
id={ id }
/>
) : (
<DefaultStepper />
defaultStepper
) }
</CardBody>
</Card>

View File

@ -1,6 +1,7 @@
/**
* External dependencies
*/
import { useMemo } from '@wordpress/element';
import { Button } from '@wordpress/components';
import { __ } from '@wordpress/i18n';
@ -38,6 +39,16 @@ const fieldTypeMap = {
default: TextField,
};
const getInitialConfigValues = ( fields: Field[] ) =>
fields.reduce(
( data, field ) => ( {
...data,
[ field.id ]:
field.type === 'checkbox' ? field.value === 'yes' : field.value,
} ),
{}
);
export const DynamicForm: React.FC< DynamicFormProps > = ( {
fields: baseFields = [],
isBusy = false,
@ -50,21 +61,13 @@ export const DynamicForm: React.FC< DynamicFormProps > = ( {
const fields =
baseFields instanceof Array ? baseFields : Object.values( baseFields );
const getInitialConfigValues = () =>
fields.reduce(
( data, field ) => ( {
...data,
[ field.id ]:
field.type === 'checkbox'
? field.value === 'yes'
: field.value,
} ),
{}
);
const initialValues = useMemo( () => getInitialConfigValues( fields ), [
fields,
] );
return (
<Form
initialValues={ getInitialConfigValues() }
initialValues={ initialValues }
onChange={ onChange }
onSubmit={ onSubmit }
validate={ validate }

View File

@ -6,7 +6,14 @@ A Slotfill component that will replace the <DynamicForm /> component involved in
```jsx
<WooPaymentGatewayConfigure id={ key }>
{({defaultForm: DefaultForm}) => <p>Fill Content</p>}
{({defaultForm: DefaultForm}) => {
return <>
<p>
Fill Content
</p>
{ defaultForm }
</>;
}}
</WooPaymentGatewayConfigure>
<WooPaymentGatewayConfigure.Slot id={ key } />
@ -16,13 +23,13 @@ A Slotfill component that will replace the <DynamicForm /> component involved in
This is the fill component. You must provide the `id` prop to identify the slot that this will occupy. If you provide a function as the child of your fill (as shown above), you will receive some helper props to assist in creating your fill:
| Name | Type | Description |
| ---------------- | --------- | -------------------------------------------------------------------------------------------------------- |
| `defaultForm` | Component | The default instance of the <DynamicForm> component. Any provided props will override the given defaults |
| `defaultSubmit` | Function | The default submit handler that is provided to the <Form> component |
| `defaultFields` | Array | An array of the field configuration objects provided by the API |
| `markConfigured` | Function | A helper function that will mark your gateway as configured |
| `paymentGateway` | Object | An object describing all of the relevant data pertaining to this payment gateway |
| Name | Type | Description |
| ---------------- | -------- | ------------------------------------------------------------------------------------------------------------------------ |
| `defaultForm` | Element | The default instance of the <DynamicForm> component. Can overwrite props using React.cloneElement(defaultForm, newProps) |
| `defaultSubmit` | Function | The default submit handler that is provided to the <Form> component |
| `defaultFields` | Array | An array of the field configuration objects provided by the API |
| `markConfigured` | Function | A helper function that will mark your gateway as configured |
| `paymentGateway` | Object | An object describing all of the relevant data pertaining to this payment gateway |
### WooPaymentGatewayConfigure.Slot (slot)