Feeds and routing (migration 4/8) - #692
Conversation
🤖 Devin AI EngineerI'll be helping with this pull request! Here's what you should know: ✅ I will automatically:
Note: I can only respond to comments from users who have write access to this repository. ⚙️ Control Options:
|
| useEffect(() => { | ||
| let ignore = false; | ||
| setErrorMessage(''); | ||
|
|
||
| fetchFeed(feedType, pageNum) | ||
| .then((nextItems) => { | ||
| if (ignore) { | ||
| return; | ||
| } | ||
|
|
||
| setItems(nextItems); | ||
| setListStart((pageNum - 1) * 30 + 1); | ||
| window.scrollTo(0, 0); | ||
| }) | ||
| .catch(() => { | ||
| if (!ignore) { | ||
| setErrorMessage(`Could not load ${feedType} stories.`); | ||
| } | ||
| }); | ||
|
|
||
| return () => { | ||
| ignore = true; | ||
| }; | ||
| }, [feedType, pageNum]); |
There was a problem hiding this comment.
🟡 Previous feed's stories remain when switching feeds
The fetch effect clears errorMessage but never resets items when feedType changes. React Router reuses the Feed instance across all feed routes, so the previous feed's stories stay visible with no loader until new data arrives; if the new feed fails to load, the stale list stays and the error is hidden.
| useEffect(() => { | |
| let ignore = false; | |
| setErrorMessage(''); | |
| fetchFeed(feedType, pageNum) | |
| .then((nextItems) => { | |
| if (ignore) { | |
| return; | |
| } | |
| setItems(nextItems); | |
| setListStart((pageNum - 1) * 30 + 1); | |
| window.scrollTo(0, 0); | |
| }) | |
| .catch(() => { | |
| if (!ignore) { | |
| setErrorMessage(`Could not load ${feedType} stories.`); | |
| } | |
| }); | |
| return () => { | |
| ignore = true; | |
| }; | |
| }, [feedType, pageNum]); | |
| useEffect(() => { | |
| let ignore = false; | |
| setItems(undefined); | |
| setErrorMessage(''); | |
| fetchFeed(feedType, pageNum) | |
| .then((nextItems) => { | |
| if (ignore) { | |
| return; | |
| } | |
| setItems(nextItems); | |
| setListStart((pageNum - 1) * 30 + 1); | |
| window.scrollTo(0, 0); | |
| }) | |
| .catch(() => { | |
| if (!ignore) { | |
| setErrorMessage(`Could not load ${feedType} stories.`); | |
| } | |
| }); | |
| return () => { | |
| ignore = true; | |
| }; | |
| }, [feedType, pageNum]); |
Was this helpful? React with 👍 or 👎 to provide feedback.
There was a problem hiding this comment.
Real bug, fixing it — but not with setItems(undefined) in the effect. Angular recreated FeedComponent when the route config changed (news → ask) while keeping the component and its list when only :page changed, so clearing in the effect would also blank the list on pagination, which the original didn't do. Adding key={feedName} to the <Feed /> route element reproduces both halves: remount (loader, no stale list) across feeds, state retained across pages.
| You can also get a job at a YC startup through <a href="https://triplebyte.com/?ref=yc_jobs">Triplebyte</a>. | ||
| </p> | ||
| )} | ||
| {feedType as string !== 'new' && ( |
There was a problem hiding this comment.
|
|
||
| function Feed({ feedType }: FeedProps) { | ||
| const params = useParams<{ page?: string }>(); | ||
| const pageNum = params.page ? Number(params.page) : 1; |
There was a problem hiding this comment.
Co-Authored-By: Charity Quinn <charity.quinn@cognition.ai>
Co-Authored-By: Charity Quinn <charity.quinn@cognition.ai>
287cbd4 to
06c1462
Compare
Summary
Stacked on #691. Ports
feeds/feed+feeds/itemand replaces PR3's placeholder outlet with the real routes, so the app is now usable end to end for browsing.Routes mirror
app.routes.ts— one parameterized route per feed, default redirect tonews/1:keyon the<Feed />element (not just the<Route />) is load-bearing. Angular destroyed and recreatedFeedComponentwhen the route config changed (news -> ask) but kept it when only:pagechanged. React Router renders the same component type in the same tree position across all five feed routes, so without the key the previous feed's stories stay on screen while the new feed loads — and hide the error if it fails. Keying onfeedNamereproduces both halves: remount across feeds, state retained across pages (which is why this isn't fixed by clearingitemsin the effect — that would also blank the list during pagination).pagecomes fromuseParams; the fetch effect is keyed on(feedType, page)and guarded by anignoreflag so a slow response for a previous page can't overwrite the current one (the Angular version re-subscribed per param change and had this race).(page - 1) * 30 + 1, "More" always renders, "prev" only past page 1.feedType !== 'new'comparison in the template (the feed name isnewest, so that branch never matches — kept as-is to avoid a behavior change inside a migration PR).Itemreads the settings context directly for title font size, list spacing and the external-linktarget/rel, instead of Angular's input-passed settings object.Verified:
yarn react:buildpasses; all five feeds render live data, pagination and ranks are correct, story links honor the "open in new tab" setting, and switching feeds shows the loader instead of the previous feed's stories while paging keeps the old list visible.Devin-Org: engineering
Link to Devin session: https://app.devin.ai/sessions/1ff25c6cf2f949458f82cc596fc79c65
Requested by: @charityquinn-cognition
Devin Review