Skip to content
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

fix(react-router): ResolvedSuspense to always use React.Suspense never the SafeFragment #1822

Open
wants to merge 5 commits into
base: main
Choose a base branch
from

Conversation

mta-trackunit
Copy link

If you create any hook that relies on a tanstack router hook - it becomes hard to test since the rerender recreates the elements again, I traced it down to this part in matches.tsx
const ResolvedSuspense = !router.state.matches.length ? React.Suspense : SafeFragment
It makes state changes with only the React.Suspense it works, dont really know if its intended or not? if so please explain how we could get around it for testing.

Copy link

nx-cloud bot commented Jun 25, 2024

☁️ Nx Cloud Report

CI is running/has finished running commands for commit 0e8f975. As they complete they will appear below. Click to see the status, the terminal output, and the build insights.

📂 See all runs for this CI Pipeline Execution


🟥 Failed Commands
nx affected --targets=test:format,test:eslint,test:unit,test:build,build --parallel=3
✅ Successfully ran 3 targets

Sent with 💌 from NxCloud.

await waitFor(() => expect(screen.getByTestId('testId')).toBeVisible());
const updated = result.current;

expect(original).toBe(updated);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This uses Object.is which will never return true since React 😅. Could you push a change with expect(original).toEqual(updated) please.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yep I will do that, thanks for replying

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

'toBe' is actually what I expect to be true here - If I have a hook and memorise a value I expect it not to change on a rerender - if I change to toEqual it will work here - but not verify that I did not get a stateChange. Testing that way will ensure the base of the hook is stabile and not causing state changes.. what do you think ?

@SeanCassiere SeanCassiere changed the title Added test to prove rerender test for hooks is not possible right now fix(react-router): ResolvedSuspense to always use React.Suspense never the SafeFragment Jun 25, 2024
@SeanCassiere
Copy link
Contributor

SeanCassiere commented Jun 25, 2024

🚨 Tested this out locally using the kitchen-sink-file-based example.

This change breaks that example where, when on/dashboard, you click "Invoices" and navigate to /dashboard/invoices, and then try clicking on "Users" to navigate to /dashboard/users, the navigation never resolves.

Edit: This breakage is weird, since now when I retested it, the above case works, but this new one breaks.

  • Load localhost:3000
  • Go to dashboard
  • Go to invoices
  • Go to users
  • Go to a user from the list
  • Go to invoices
  • Try going to an invoice and notice the navigation doesn't actually resolve.

@mta-trackunit
Copy link
Author

mta-trackunit commented Jun 26, 2024

So navigating from http:https://localhost:5173/dashboard/invoices
to (using menu) http:https://localhost:5173/dashboard/users
It navigates to
http:https://localhost:5173/dashboard/invoices?usersView=%7B%7D

So it seems like tanstack router is behind 1 "tick" ... any idea how to debug that?

In examples/react/kitchen-sink-file-based/src/routes/dashboard.users.tsx

  React.useEffect(() => {
    navigate({
      search: (old) => {
        return {
          ...old,
          usersView: {
            ...old?.usersView,
            filterBy: filterDraft || undefined,
          },
        }
      },
      replace: true,
    })
  }, [filterDraft])

That seems to navigate - so it feels like tanstack router is behind and redirects so updating search on first render here navigates back to previous route (invoices).

A solution is to add to navigate function

 to: "/dashboard/users",

but it clearly hides some other bug...

… would end up redirecting back to dashboard/invoices if using this.state.resolvedLocation
// and the new matches could already render
const currentLocation = this.state.isLoading
? this.state.resolvedLocation
: this.latestLocation
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change made the kitchensink app work - but dont know what other consequence it will have? maybe my change is not the right solution - but it solves the kitchensink app navigate from invoices to users

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants