Skip to content

Conversation

@chorobin
Copy link
Contributor

@chorobin chorobin commented Aug 7, 2024

This PR adds context to each route

@nx-cloud
Copy link

nx-cloud bot commented Aug 7, 2024

☁️ Nx Cloud Report

CI is running/has finished running commands for commit 82e7a90. 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


✅ Successfully ran 2 targets

Sent with 💌 from NxCloud.

@chorobin
Copy link
Contributor Author

chorobin commented Aug 7, 2024

  • Type tests
  • Optimize & refactor types a bit

@chorobin
Copy link
Contributor Author

chorobin commented Aug 7, 2024

Lets not force push this one if multiple of us are working on it. Merge only!

@pkg-pr-new
Copy link

pkg-pr-new bot commented Aug 7, 2024

commit: 82e7a90

@tanstack/history

pnpm add https://pkg.pr.new/@tanstack/history@2104

@tanstack/react-cross-context

pnpm add https://pkg.pr.new/@tanstack/react-cross-context@2104

@tanstack/react-router

pnpm add https://pkg.pr.new/@tanstack/react-router@2104

@tanstack/react-router-with-query

pnpm add https://pkg.pr.new/@tanstack/react-router-with-query@2104

@tanstack/router-arktype-adapter

pnpm add https://pkg.pr.new/@tanstack/router-arktype-adapter@2104

@tanstack/router-cli

pnpm add https://pkg.pr.new/@tanstack/router-cli@2104

@tanstack/router-devtools

pnpm add https://pkg.pr.new/@tanstack/router-devtools@2104

@tanstack/router-generator

pnpm add https://pkg.pr.new/@tanstack/router-generator@2104

@tanstack/router-plugin

pnpm add https://pkg.pr.new/@tanstack/router-plugin@2104

@tanstack/router-valibot-adapter

pnpm add https://pkg.pr.new/@tanstack/router-valibot-adapter@2104

@tanstack/router-vite-plugin

pnpm add https://pkg.pr.new/@tanstack/router-vite-plugin@2104

@tanstack/router-zod-adapter

pnpm add https://pkg.pr.new/@tanstack/router-zod-adapter@2104

@tanstack/start

pnpm add https://pkg.pr.new/@tanstack/start@2104

@tanstack/start-vite-plugin

pnpm add https://pkg.pr.new/@tanstack/start-vite-plugin@2104

Open in Stackblitz

More templates

@chorobin chorobin requested a review from SeanCassiere August 7, 2024 19:35
>,
) => any)

routeContext?: Constrain<
Copy link
Contributor Author

@chorobin chorobin Aug 7, 2024

Choose a reason for hiding this comment

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

Limitations of default type parameters and constraints leads me to use this pattern which I've made into a utility type. Long story short, its easy to get stale types which are the default types/constraints and not the inferred types.

Instead Constrain is a conditional type which checks if a type is assignable to another type, if it is then all good, we can infer the type, otherwise we use the target type to force a type check error. This always gives us the up to date types from inference as the conditional type is always ran

TLoaderDeps extends Record<string, any> = {},
TLoaderDataReturn = {},
TParentAllContext = {},
TRouteContextFn = AnyContext,
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'm trying out patterns to remove unnecessary type parameters. Usually we require 2 type parameters per function because we need to check the return type is never. If we infer the whole function, we don't need two type paramters

@tannerlinsley
Copy link
Collaborator

@chorobin I hope this doesn't screw anything up, but I removed routeContext from RouteMatch. Route remains untouched. There just wasn't any use for it in the match and in fact, since we're doing immutable updates to matches, it never made much sense to have a separate routeContext and context for the match.

Now it's just context. This okay?

@tannerlinsley
Copy link
Collaborator

Fudge. We might need to keep it, but only as a runtime thing. I don't want people relying on it as a public API, but I do need it to build up merges correctly...

@chorobin
Copy link
Contributor Author

@chorobin I hope this doesn't screw anything up, but I removed routeContext from RouteMatch. Route remains untouched. There just wasn't any use for it in the match and in fact, since we're doing immutable updates to matches, it never made much sense to have a separate routeContext and context for the match.

Now it's just context. This okay?

No problem from my side on this. It probably would be confusing to keep it

@SeanCassiere SeanCassiere linked an issue Aug 16, 2024 that may be closed by this pull request
@tannerlinsley
Copy link
Collaborator

@SeanCassiere @chorobin @schiller-manuel we good here?

SeanCassiere

This comment was marked as resolved.

@tannerlinsley
Copy link
Collaborator

tannerlinsley commented Aug 17, 2024 via email

* chore: type the objects used for `routeContext` and `beforeLoad`

* refactor: move the defaultTransformer from start to react-router

* test: add tests to the defaultTransformer
navigate: (opts: any) =>
this.navigate({ ...opts, _fromLocation: next }),
buildLocation: this.buildLocation,
cause: match.cause,
Copy link
Member

Choose a reason for hiding this comment

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

@tannerlinsley not sure if this was intentionally omitted or not, but cause, abortController, and preload, were not present on this object before but were typed on the RouteContextOptions type.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah, I made it the same as beforeLoad in this regard. If the types are wrong here they can be removed

Copy link
Contributor

Choose a reason for hiding this comment

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

could we take this chance to add previous and next location (in parsed form) as params to all of those functions?

Copy link
Member

Choose a reason for hiding this comment

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

@schiller-manuel I'd push for that kind of change to go separate from this PR.

A change of this nature would require more sweeping changes to make sure those values are present in the loadMatches function, whilst not really contributing to the task of adding this context function to the route definition and wiring it up.

Once this goes in, if we are adding in the previous and next location options into the shared definition used for context, beforeLoad, and the loader, it'd certainly be more straight-forward.

@SeanCassiere SeanCassiere changed the title feat(react-router): add routeContext to route feat(react-router): add context option to route Aug 20, 2024
@tannerlinsley tannerlinsley merged commit 42f703d into main Aug 20, 2024
@tannerlinsley tannerlinsley deleted the route-context branch August 20, 2024 19:39
@shfrmn
Copy link

shfrmn commented Aug 22, 2024

@tannerlinsley Thank you for the work on the library. I thought this would be an appropriate place to ask some questions, since you just closed this PR very recently.

  1. What is the difference between context and beforeLoad? For now documentation is not updated to explain the context option. I assume context does not block component rendering? Or does it?
  2. What is the reason the context type is not restricted by the root route? Meaning, beforeLoad and context can set a context of type that's different from the defined root context type or not return any context at all. I expected to get TypeScript errors in those cases to prevent incorrect context states. For example, breadcrumbs feature requires every page to have a title, but there is apparently no way to enforce this on the type level.
  3. Since context is inherited from the parent component, there's an undesired side effect when using it for features like breadcrumbs. Let's say we have a route /user/$userId. While user object is being loaded, the breadcrumb data will end up being duplicated, something like [{pageTitle: "Users"}, {pageTitle: "Users"}] (because the second match initially inherits the context identical to the first). It would be helpful to have some way to prevent context inheritance. Perhaps context + beforeLoad actually allow to achieve that, but I can't be sure. If not perhaps some boolean flag could do. Does it make any sense?

Update: Tested preventing inheritance of context state using context + beforeLoad and it worked. I think this would be good to mention in documentation too.

Thank you and have a good day!

@SeanCassiere
Copy link
Member

1 will be documented, we just haven't gotten around to it yet.

If anything is breaking, please create an issue for it. These closed PRs don't get much visibility in our inboxes 😅

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.

defaultTransformer is not being set in <StartClient /> in @tanstack/start 1.47.1 Release introduces hydration errors

5 participants