Skip to content

Commit d6cc72e

Browse files
committed
feat(core): CHECKOUT-9513 Pass in initial state in separate microtask
1 parent 1c54ac3 commit d6cc72e

File tree

8 files changed

+148
-153
lines changed

8 files changed

+148
-153
lines changed

package-lock.json

Lines changed: 3 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@
4848
"prettier": "@bigcommerce/eslint-config/prettier",
4949
"homepage": "https://github.com/bigcommerce/checkout-js#readme",
5050
"dependencies": {
51-
"@bigcommerce/checkout-sdk": "github:bigcommerce/checkout-sdk-js#dbc080e6cd4d6647ec15d5c50916e9a70cd31007",
51+
"@bigcommerce/checkout-sdk": "github:bigcommerce/checkout-sdk-js#f2438c3ba5fa581035772cbc7bc9e909ea00c1f2",
5252
"@bigcommerce/citadel": "^2.15.1",
5353
"@bigcommerce/form-poster": "^1.2.2",
5454
"@bigcommerce/memoize": "^1.0.0",

packages/core/src/app/billing/Billing.test.tsx

Lines changed: 41 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import {
22
type BillingAddress,
3-
type CheckoutInitialState,
43
type CheckoutService,
54
createCheckoutService,
65
createEmbeddedCheckoutMessenger,
@@ -40,7 +39,8 @@ import {
4039
import { act, renderWithoutWrapper as render, screen } from '@bigcommerce/checkout/test-utils';
4140
import { ThemeProvider } from '@bigcommerce/checkout/ui';
4241

43-
import Checkout, { type CheckoutProps } from '../checkout/Checkout';
42+
import Checkout from '../checkout/Checkout';
43+
import { type CheckoutIntermediateProps } from '../checkout/CheckoutIntermediate';
4444
import { getCheckoutPayment } from '../checkout/checkouts.mock';
4545
import { createErrorLogger } from '../common/error';
4646
import {
@@ -50,9 +50,9 @@ import {
5050

5151
describe('Billing step', () => {
5252
let checkout: CheckoutPageNodeObject;
53-
let CheckoutTest: FunctionComponent<CheckoutProps>;
53+
let CheckoutTest: FunctionComponent<CheckoutIntermediateProps>;
5454
let checkoutService: CheckoutService;
55-
let defaultProps: CheckoutProps & AnalyticsContextProps;
55+
let defaultProps: CheckoutIntermediateProps & AnalyticsContextProps;
5656
let embeddedMessengerMock: EmbeddedCheckoutMessenger;
5757
let analyticsTracker: Partial<AnalyticsEvents>;
5858

@@ -193,16 +193,15 @@ describe('Billing step', () => {
193193
});
194194

195195
it('should show order comments', async () => {
196-
checkoutService = createCheckoutService({
197-
initialState: {
198-
config: checkoutSettings,
199-
checkout: {
200-
...checkoutWithBillingEmail,
201-
cart: checkoutWithDigitalCart.cart,
202-
},
203-
formFields,
196+
defaultProps.initialState = {
197+
config: checkoutSettings,
198+
checkout: {
199+
...checkoutWithBillingEmail,
200+
cart: checkoutWithDigitalCart.cart,
204201
},
205-
});
202+
formFields,
203+
extensions: [],
204+
};
206205

207206
render(<CheckoutTest {...defaultProps} />);
208207

@@ -212,19 +211,18 @@ describe('Billing step', () => {
212211
});
213212

214213
it('should show PoweredByPayPalFastlaneLabel', async () => {
215-
checkoutService = createCheckoutService({
216-
initialState: {
217-
config: checkoutSettings,
218-
checkout: {
219-
...checkoutWithShipping,
220-
billingAddress:checkoutWithBillingEmail.billingAddress,
221-
payments:[
222-
getCheckoutPayment(),
223-
],
224-
},
225-
formFields,
214+
defaultProps.initialState = {
215+
config: checkoutSettings,
216+
checkout: {
217+
...checkoutWithShipping,
218+
billingAddress:checkoutWithBillingEmail.billingAddress,
219+
payments:[
220+
getCheckoutPayment(),
221+
],
226222
},
227-
});
223+
formFields,
224+
extensions: [],
225+
};
228226

229227
render(<CheckoutTest {...defaultProps} />);
230228

@@ -302,13 +300,12 @@ describe('Billing step', () => {
302300

303301
describe('registered customer', () => {
304302
it('completes the billing step after selecting a valid address', async () => {
305-
checkoutService = createCheckoutService({
306-
initialState: {
307-
config: checkoutSettings,
308-
checkout: checkoutWithCustomer,
309-
formFields,
310-
},
311-
});
303+
defaultProps.initialState = {
304+
config: checkoutSettings,
305+
checkout: checkoutWithCustomer,
306+
formFields,
307+
extensions: [],
308+
};
312309

313310
jest.spyOn(checkoutService, 'updateBillingAddress');
314311

@@ -368,13 +365,12 @@ describe('Billing step', () => {
368365
phone: shippingAddress3.phone,
369366
} as BillingAddress;
370367

371-
checkoutService = createCheckoutService({
372-
initialState: {
373-
config: checkoutSettings,
374-
checkout: checkoutWithCustomer,
375-
formFields,
376-
},
377-
});
368+
defaultProps.initialState ={
369+
config: checkoutSettings,
370+
checkout: checkoutWithCustomer,
371+
formFields,
372+
extensions: [],
373+
};
378374

379375
jest.spyOn(checkoutService, 'updateBillingAddress');
380376

@@ -423,13 +419,12 @@ describe('Billing step', () => {
423419
});
424420

425421
it('completes the billing step after creating a new address even with existing addresses', async () => {
426-
checkoutService = createCheckoutService({
427-
initialState: {
428-
config: checkoutSettings,
429-
checkout: checkoutWithCustomer,
430-
formFields,
431-
},
432-
});
422+
defaultProps.initialState = {
423+
config: checkoutSettings,
424+
checkout: checkoutWithCustomer,
425+
formFields,
426+
extensions: [],
427+
};
433428

434429
jest.spyOn(checkoutService, 'updateBillingAddress');
435430

packages/core/src/app/checkout/CheckoutApp.tsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,6 @@ const CheckoutApp = (props: CheckoutAppProps): ReactElement => {
3535
const checkoutService = useMemo(() => createCheckoutService({
3636
locale: getLanguageService().getLocale(),
3737
shouldWarnMutation: process.env.NODE_ENV === 'development',
38-
initialState: props.initialState,
3938
}), []);
4039
const embeddedStylesheet = useMemo(() => createEmbeddedCheckoutStylesheet(), []);
4140
const embeddedSupport = useMemo(() => createEmbeddedCheckoutSupport(getLanguageService()), []);

packages/core/src/app/checkout/CheckoutIntermediate.tsx

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import {
2+
type CheckoutInitialState,
23
type EmbeddedCheckoutMessenger,
34
type EmbeddedCheckoutMessengerOptions
45
} from '@bigcommerce/checkout-sdk';
@@ -13,18 +14,19 @@ import CheckoutPage from './CheckoutPage';
1314
import type CheckoutSupport from './CheckoutSupport';
1415
import { useLoadCheckout } from './hooks';
1516

16-
interface CheckoutIntermediateProps {
17+
export interface CheckoutIntermediateProps {
1718
checkoutId: string;
1819
containerId: string;
1920
embeddedStylesheet: EmbeddedCheckoutStylesheet;
2021
embeddedSupport: CheckoutSupport;
2122
errorLogger: ErrorLogger;
23+
initialState?: CheckoutInitialState;
2224
createEmbeddedMessenger(options: EmbeddedCheckoutMessengerOptions): EmbeddedCheckoutMessenger;
2325
}
2426

2527
const CheckoutIntermediate:React.FC<CheckoutIntermediateProps>= (props) => {
26-
const { checkoutId } = props;
27-
const { isLoadingCheckout } = useLoadCheckout(checkoutId);
28+
const { checkoutId, initialState } = props;
29+
const { isLoadingCheckout } = useLoadCheckout(checkoutId, initialState);
2830
const { themeV2 } = useThemeContext();
2931

3032
if (isLoadingCheckout) {

packages/core/src/app/checkout/hooks/useLoadCheckout.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ describe('useLoadCheckout', () => {
8181
const mockCheckoutState = {
8282
data: {
8383
getCheckout,
84-
}
84+
},
8585
};
8686

8787
(useCheckout as jest.Mock).mockReturnValue({

packages/core/src/app/checkout/hooks/useLoadCheckout.ts

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
1+
import { type CheckoutInitialState } from '@bigcommerce/checkout-sdk';
12
import { useEffect, useState } from 'react';
23

34
import { useExtensions } from '@bigcommerce/checkout/checkout-extension';
45
import { useCheckout } from '@bigcommerce/checkout/payment-integration-api';
56

6-
export const useLoadCheckout = (checkoutId: string): {isLoadingCheckout: boolean} => {
7+
export const useLoadCheckout = (checkoutId: string, initialState?: CheckoutInitialState): {isLoadingCheckout: boolean} => {
78
const { checkoutService, checkoutState: { data } } = useCheckout();
8-
const initialStateLoaded = !!data.getCheckout();
9-
const [ isLoadingCheckout, setIsLoadingCheckout ] = useState(!initialStateLoaded);
9+
const [ isLoadingCheckout, setIsLoadingCheckout ] = useState(!data.getCheckout());
1010
const { extensionService } = useExtensions();
1111

1212
const fetchData = async () => {
@@ -44,13 +44,22 @@ export const useLoadCheckout = (checkoutId: string): {isLoadingCheckout: boolean
4444
};
4545

4646
useEffect(() => {
47-
if (!initialStateLoaded) {
47+
if (!isLoadingCheckout) {
48+
return;
49+
}
50+
51+
if (!initialState) {
4852
// If the initial data has not been preloaded from the server, we need to make API calls to fetch it.
4953
fetchDataWithRetry()
5054
.then(() => setIsLoadingCheckout(false))
5155
.catch((error) => {
5256
throw error;
5357
});
58+
} else {
59+
requestAnimationFrame(async () => {
60+
await checkoutService.hydrateInitialState(initialState);
61+
setIsLoadingCheckout(false);
62+
});
5463
}
5564
}, []);
5665

0 commit comments

Comments
 (0)