fix: stop the course outline scrolling back while you work in it - #3213
fix: stop the course outline scrolling back while you work in it#3213ihor-romaniuk wants to merge 1 commit into
Conversation
|
Thanks for the pull request, @ihor-romaniuk! This repository is currently maintained by Once you've gone through the following steps feel free to tag them in a comment and let them know that your changes are ready for engineering review. 🔘 Get product approvalIf you haven't already, check this list to see if your contribution needs to go through the product review process.
🔘 Provide contextTo help your reviewers and other members of the community understand the purpose and larger context of your changes, feel free to add as much of the following information to the PR description as you can:
🔘 Get a green buildIf one or more checks are failing, continue working on your changes until this is no longer the case and your build turns green. DetailsWhere can I find more information?If you'd like to get more details on all aspects of the review process for open source pull requests (OSPRs), check out the following resources: When can I expect my changes to be merged?Our goal is to get community contributions seen and reviewed as efficiently as possible. However, the amount of time that it takes to review and merge a PR can vary significantly based on factors such as:
💡 As a result it may take up to several weeks or months to complete a review and merge your PR. |
9f24e83 to
c2ec4a7
Compare
Opening a course outline through a link that points at one of its blocks left the page snapping back to that block on almost every interaction — opening a section menu was enough. The block stays highlighted for as long as the link is in the address bar, and the outline reads that as "scroll to it" again each time it re-renders. The global-state hook handed out a new pair of callbacks on every render, and the cards that scroll to the highlighted block list one of those callbacks among the dependencies of the effect that scrolls. The callbacks now keep their identity, so the effect runs when the highlighted block changes rather than on every render. Scrolling to the block on arrival is unchanged.
c2ec4a7 to
344320b
Compare
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## master #3213 +/- ##
=======================================
Coverage 95.92% 95.92%
=======================================
Files 1397 1397
Lines 33581 33582 +1
Branches 7947 7921 -26
=======================================
+ Hits 32214 32215 +1
Misses 1308 1308
Partials 59 59 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
|
I believe this has already been fixed on master. I just tested it now and could not reproduce the issue.
I don't think this is correct, because Nevertheless, it may still be worth merging this PR. The However, I'm wondering why we even have @navinkarkera what do you think? could you please review this? |
navinkarkera
left a comment
There was a problem hiding this comment.
Even I was not able to reproduce the issue.
But I agree with @bradenmacdonald , it is still worth merging.
However, I'm wondering why we even have createGlobalState at all - it's a bit of a hack to share state among components using React Query, but it's not using any of the query lifecycle or fetching features (staleness, refetching, invalidation). It would be cleaner to use a small context or perhaps useSyncExternalStore.
Yes, I added it while refactoring outline page and simplifying storage, it felt cleaner to have react query manage the state but I agree that it would be better to use a context (don't remember why I did not do it).
| }; | ||
|
|
||
| /** | ||
| * Create a global state function for a query. |
There was a problem hiding this comment.
@ihor-romaniuk Can you please just make this change to the comment here, and then I'll merge this fix?
--- a/src/data/apiHooks.ts
+++ b/src/data/apiHooks.ts
@@ -152,7 +152,12 @@ export const useCourseDetails = (courseId: string) => {
};
/**
- * Create a global state function for a query.
+ * Create a global state function.
+ *
+ * This is sort of a hack for sharing state between components using React Query
+ * without actually loading data from an API. Instead of using this, please use
+ * a small context or `useSyncExternalStore`, and feel free to remove this once
+ * we've replaced the existing usage of it on the outline page.
*/
export function createGlobalState<T>(
queryKeyFn: (queryKeyArgs?: any) => QueryKey,
Description
Open a course outline through a link that points at one of its blocks — the kind Studio search and "view in outline" produce, with
?show=<block>in the address — and the page starts snapping back to that block. Opening the menu on any section is enough to be thrown back to it, which makes the outline hard to work in at all. The block stays highlighted for as long as the link is in the address bar, and the outline reads that as "scroll to it" every time it re-renders.The outline now scrolls to the highlighted block when you arrive and then leaves the page alone.
Implementation notes
createGlobalStateinsrc/data/apiHooks.tsreturnedsetDataandresetDataas plain functions declared in the hook body, so both got a new identity on every render.SectionCard,SubsectionCardandUnitCardlistresetScrollStateamong the dependencies of the effect that callsscrollToElement, so that effect ran on every render. While?show=names the card, its guardisScrolledToElementstays true, so every render scrolled. The effect also callsresetScrollState(), which invalidates the query and causes another render — hence repeated jumps rather than one.useQuery'srefetchdoes.queryKeyis memoised onqueryKeyArgsso the callbacks can depend on it honestly, without a ref.createGlobalState.Screenshot/Video
Before
before.mov
After
after.mov
Testing
Preconditions: a course with several sections, a staff user.
<AUTHORING>/course/<courseId>?show=<sectionId>.?show=and repeat.Verified locally
?show=<section>, scrolled to 6000px, section menu openedaria-expandedflips and the dropdown rendersjest src/course-outlinejest src/data/apiHooks.test.tsxtsc,dprint,oxlint