-
Notifications
You must be signed in to change notification settings - Fork 326
Fix stale product options #1210
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
Conversation
ce43bf8 to
b5c9499
Compare
| ReactApp: JSX.Element, | ||
| {log, nonce}: {log: Logger; nonce?: string} | ||
| ): Promise<string> { | ||
| return new Promise<string>(async (resolve, reject) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is something caught by the linter that I think we should avoid. Having an async function as the resolver of a Promise. The issue is that uncaught errors within the async function won't bubble to any outer .catch statements
| children, | ||
| }) => { | ||
| if (META_ENV_SSR) return <>{children}</>; | ||
| /* eslint-disable react-hooks/rules-of-hooks */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This intentionally runs slightly different in SSR mode
| // eslint-disable-next-line react-hooks/rules-of-hooks | ||
| return useMemo(() => new URL(window.location.href), [location]); // eslint-disable-line react-hooks/exhaustive-deps |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This memoization is interesting. I assume it is correct. But at the same time I'm wondering if it maybe should be useMemo(() => new URL(location.href), [location]);?
| }); | ||
| }); | ||
|
|
||
| it('computes selected variant based on options', async () => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This test was essentially doing exactly what the other one was.
| }, [initialVariantId, variants]); | ||
| const variant = getSelectedVariant(variants, selectedOptions); | ||
| setSelectedVariant(variant); | ||
| }, [selectedOptions, variants]); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I simplified the two effects in here into just one.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice
frehner
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks so good!
| clientState, | ||
| onClick, | ||
| location, | ||
| navigate, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Rules of hooks, yay
| return ( | ||
| <div className={className} tabIndex={1}> | ||
| /* eslint-disable jsx-a11y/no-noninteractive-tabindex */ | ||
| <div className={className} tabIndex={0}> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hm, this is a weird one. I feel like it would actually make more sense to have the tabindex on the custom element, but I don't know enough to know if that's correct or not.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, I don't know either. I think it should be looked at in a separate PR?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't have a lot of context here, but from my observation... Pressing Enter when focused on this div here should have no effect so it shouldn't be tab-able IMO. In other words: the tabIndex should be removed (and the disable comment with it).
Adding tabIndex to the custom component would make sense to me too, but has no effect either when you hit Enter. I think this interaction/event-handling needs to be handled within the script that controls the component (the third-party shop-js/client script).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So I think the solution here is for the custom component to handle its own focus events internally, and we shouldn't have any tabIndex attribute overrides.
| } else { | ||
| navigate(to); | ||
| } | ||
| // eslint-disable-next-line react-hooks/exhaustive-deps |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Any particular reason we want to ignore this one?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was getting weird issues where it would execute twice, and the page wouldn't redirect. Because it's a redirect, it shouldn't matter though.
| }, [initialVariantId, variants]); | ||
| const variant = getSelectedVariant(variants, selectedOptions); | ||
| setSelectedVariant(variant); | ||
| }, [selectedOptions, variants]); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice
0340b93 to
9e82836
Compare
|
👋 It looks like you're updating JavaScript packages that are known You can deduplicate them with the If running these commands doesn't produce a change in your yarn.lock file, A duplicate React version may cause an invalid hook call warning. React context providers usually use module-scoped globals as their |
|
|
||
| const value = useMemo( | ||
| () => standardCurrencyFormatter.format(amount), | ||
| () => new Intl.NumberFormat(locale, options).format(amount), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Might as well mov Intl.NumberFormat into the memo 🤘
jplhomer
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the diligent work!
* v1.x-2022-07: Fix stale product options (#1210) Upgrade body-parser in hydrogen package (#1232) Add new options to Money and useMoney (#1215) fix links (#1229) Update turbo and instructions for developing `dev` (#1225) Heck - deploy all branches to Oxygen add context for initialvariantid (#1217) Build chunks are inside assets folder (#1211) Upgraded to SFAPI 2022-07 (#1214) [ci] release v1.x-2022-07 (#1205) Make this a patch instead of minor add references to video in file_reference block (#1197) Laying the foundation for building components in isolation (#1188) Make metafields optional within the ProductProvider. Fixes #1127 (#1209) Add README to /templates directory (#1163) fix perf tracking and make it optional from developer's end (#1096) docs fixes (#1204)
This comes up when you directly navigate from one product to another, and the product options are not the same. See this stackblitz. Notice the related products at the bottom of the details page that allow you to navigate directly to other products. As you do so, the product options get lost.
The bigger issue exposed here is that we don't lint our framework code. I updated this PR to now lint! Because of that, there are a lot of other changes. I commented throughout the PR on more significant things found by the linter.