Change dioxus_router to require explicitly setting components to be used
Feature Request
The current implementation of the Routable macro pulls in components from the namespace by default.
However this can make it quite unclear what is being used and forces users to keep names consistent between the components and routers.
This can also mess with people ide's workflows, as many people (myself included) have binds for going to the definition of something or renaming all instances of a identity.
#[rustfmt::skip]
#[derive(Clone, Debug, PartialEq, Routable)]
enum Route {
#[nest("/blog")]
#[layout(Blog)]
#[route("/")]
BlogList {},
#[route("/:blog_id")]
BlogPost { blog_id: usize },
#[end_layout]
#[end_nest]
#[route("/")]
Index {},
}
Implement Suggestion
Force the explicit use of components in for each route of the router instead of implicitly finding them in the namespace, in order to make it clearer what's being used and to stop namespace collisions.
#[rustfmt::skip]
#[derive(Clone, Debug, PartialEq, Routable)]
enum Route {
#[nest("/blog")]
#[layout(Blog)]
#[route("/", BlogList)]
BlogList {},
#[route("/:blog_id", BlogPost)]
BlogPost { blog_id: usize },
#[end_layout]
#[end_nest]
#[route("/", Home)]
Index {},
}
For reference bevy uses a similar idea in their relationship macros.
#[derive(Component)]
#[relationship_target(relationship = ChildOf)]
pub struct Children(Vec<Entity);
Perhaps this could even be extended to accept a closure that takes in whatever arguments are specified by the enum variant, such as
#[rustfmt::skip]
#[derive(Clone, Debug, PartialEq, Routable)]
enum Route {
// Obviously there's not much point to doing it here, but it would allow people to do complex conversions that can't be done with FromStr such as composing data from multiple variables
#[route("/post/:post_id")]
#[route_component(|id| rsx!{
Post { id: id }
})]
Post { post_id: usize },
#[route("/")]
#[route_component(Home)]
Index {},
}
Though I may just be getting ahead of myself
Didn't see it documented, but looking at the macro it seems route does allow an optional second argument for the component. https://github.com/DioxusLabs/dioxus/blob/4f74ef81d1225829d92440bd7da6861045a4738a/packages/router-macro/src/route.rs#L33-L36
I'm afk, but it seems like #[route("/", Home)] should do what you need.
Ah right, in that case it's probably a good idea to point it out. I'd still recommend reworking it so that it's required since the current default way feels very unstable but it's good to know there is a way to do this
Nvm, it is documented in the router macro crate. https://docs.rs/dioxus-router-macro/latest/dioxus_router_macro/derive.Routable.html
Visibility could be better that's true.
The closure feature I pointed out seems to be documented there as well which is cool.
Oh no that's for redirects
Yeah, but given it already exists for redirects it doesn't seem like a stretch to add it for normal routes too.
If the team wants it I could give it a go. Making the component required would be breaking so that's up to them to decide if and when, but maybe we could add a clippy warning or something allowing you to opt-in to that enforcement.