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

Router breaks if it's in its own module #2903

Closed
1 of 3 tasks
sasacocic opened this issue Oct 2, 2022 · 7 comments · Fixed by #2913
Closed
1 of 3 tasks

Router breaks if it's in its own module #2903

sasacocic opened this issue Oct 2, 2022 · 7 comments · Fixed by #2913
Labels
A-yew-router Area: The yew-router crate documentation

Comments

@sasacocic
Copy link
Contributor

sasacocic commented Oct 2, 2022

Problem

If you setup routes in their own module and import them to use them it doesn't work.

Steps To Reproduce
Steps to reproduce the behavior:

  1. Create a new Rust binary with default structure
  2. Add a router.rs module
...
src
  - main.rs
  - router.rs
 Cargo.toml
....
  1. Copy and past the code to associated files
    router.rs
use crate::*;
use yew_router::prelude::*;

#[derive(Clone, Routable, PartialEq)]
pub enum Route {
    #[at("/")]
    Home,
    #[at("/profile")]
    Profile,
    #[not_found]
    #[at("/404")]
    NotFound,
}

pub fn switch(routes: &Route) -> Html {
    match routes {
        Route::Home => html! { <Home/> },
        Route::Profile => html! { <Profile /> },
        Route::NotFound => html! { <div>{"the location you've gone to doesn't exist :("}</div>},
    }
}

#[function_component(BaseRouter)]
pub fn base_router() -> Html {
    html! {
        <BrowserRouter>
            <Switch <Route> render={Switch::render(switch)} />
        </BrowserRouter>
    }
}

main.rs

use yew::prelude::*;
mod router;
use router::*;
use yew_router::prelude::*;

#[function_component(Home)]
pub fn home() -> Html {
    html! {
        <div>{"home"}</div>
    }
}

#[function_component(Profile)]
pub fn profile() -> Html {
    html! {
        <div>{"profile"}</div>
    }
}

#[function_component(App)]
pub fn app() -> Html {
    html! {
        <li>
            <li><Link<Route> to={Route::Home}>{ "home" }</Link<Route>></li>
            <li><Link<Route> to={Route::Profile}>{ "profile" }</Link<Route>></li>

        </li>
    }
}

fn main() {
    wasm_logger::init(wasm_logger::Config::default());
    yew::start_app::<App>();
}
  1. Run trunk serve --open

Expected behavior
The router to not crash

Screenshots
Screen Shot 2022-10-02 at 8 38 41 AM

Environment:

  • Yew version: 0.19.3
  • yew_router version: 0.16.0
  • Rust version: rustc 1.63.0
  • Target: wasm32-unknown-unknown
  • Build tool, if relevant: trunk
  • OS: MacOS
  • Browser: Firefox 105.0.1 - I also tried on chrome, but got the same error

Questionnaire

  • I'm interested in fixing this myself but don't know where to start
  • I would like to fix and I have a solution
  • I don't have time to fix this right now, but maybe later

also I tried

  • changing the use statements - kind of just shots in the dark as I though multiple imports might make things weird, but I had no luck with this
@sasacocic sasacocic added the bug label Oct 2, 2022
@WorldSEnder WorldSEnder added documentation A-yew-router Area: The yew-router crate and removed bug labels Oct 2, 2022
@WorldSEnder
Copy link
Member

WorldSEnder commented Oct 2, 2022

The problem is a different one, and I assume that what should be done is to improve the documentation of that issue.
Route components, like Link and Switch need to be render in the context (i.e. as grandchildren) of one of the *Router components.

I suppose this should be spelled out better in the router docs and the error could also mention that it expects this (instead of just reading "failed to read history"). The current formulation

Finally, you need to register one of the Router context provider components like <BrowserRouter />. It provides location information and navigator to its children.

seems not clear enough in that regard.

@sasacocic
Copy link
Contributor Author

sasacocic commented Oct 2, 2022

Ok this makes sense. I think that's how react-router also works. Changing

main.rs

use yew::prelude::*;
mod router;
use router::*;
use yew_router::prelude::*;

#[function_component(Home)]
pub fn home() -> Html {
    html! {
        <div>
            <li>
                <li><Link<Route> to={Route::Home}>{ "home" }</Link<Route>></li>
                <li><Link<Route> to={Route::Profile}>{ "profile" }</Link<Route>></li>
            </li>
        </div>
    }
}

#[function_component(Profile)]
pub fn profile() -> Html {
    html! {
        <div>{"profile"}</div>
    }
}

#[function_component(App)]
pub fn app() -> Html {
    html! {
        <BaseRouter/>
    }
}

fn main() {
    wasm_logger::init(wasm_logger::Config::default());
    yew::start_app::<App>();
}

and router.rs to

use crate::*;
use yew_router::prelude::*;

#[derive(Clone, Routable, PartialEq)]
pub enum Route {
    #[at("/")]
    Home,
    #[at("/profile")]
    Profile,
    #[not_found]
    #[at("/404")]
    NotFound,
}

pub fn switch(routes: &Route) -> Html {
    match routes {
        Route::Home => html! { <Home/> },
        Route::Profile => html! { <Profile /> },
        Route::NotFound => html! { <div>{"the location you've gone to doesn't exist :("}</div>},
    }
}

#[function_component(BaseRouter)]
pub fn base_router() -> Html {
    html! {
        <BrowserRouter>
            <Switch <Route> render={Switch::render(switch)} />
        </BrowserRouter>
    }
}

It now works!

Also, In the latest docs

Finally, you need to register the <Router /> component as a context. <Router /> provides session history information to its children.

I assume "Registering" the router just mean rendering it in the html! macro? If so I think this should just say "it needs to be rendered"

Also, completely aside I've found the existing documentation to be overly verbose, and not very useful. It goes into too much detail about how things work (I think that's good if I'm looking at reference documentation, but in this case I'm just trying to figure out how to get some code to work or understand a concept in Yew). Also, for why I haven't found it that useful it could be a number of reasons (one being coming from React I expect things to function somewhat similarly and I think that's what Yew intends to do, but I could be wrong about this - also I haven't read the documentation super carefully) - Also if you look at Reacts documentation it's nicely split between concepts and API reference - which Yew could potentially do something similar.

Anyways I'd be happy to contribute to restructuring docs / improving existing ones to be better. What's the best way to go about doing that? Just open up a PR?

@sasacocic sasacocic reopened this Oct 3, 2022
@WorldSEnder
Copy link
Member

Yeah if you want to PR an improved version, that would be the way to go and appreciated :) Further feedback and review will then be there, just get your feet wet and ask questions if you're unsure where to put stuff. For starters, the files you'd want to look for are https://github.com/yewstack/yew/blob/master/website/docs/concepts/router.mdx and if you want to fix it in the docs for 0.19 as well, that's in https://github.com/yewstack/yew/blob/master/website/versioned_docs/version-0.19.0/concepts/router.mdx (less important). The website can be built locally just follow the steps in https://github.com/yewstack/yew/blob/master/website/README.md

@sasacocic
Copy link
Contributor Author

sasacocic commented Oct 7, 2022

Locally I've made the changes, but I'm unable to push a branch up to this repo and create a PR. I looked at the contributing doc, but it didn't mention anything about opening a PR.

How can I get my changes looked at?

@WorldSEnder
Copy link
Member

You can create a fork of this repo, there you have permission to push and then issue a PR.

@sasacocic
Copy link
Contributor Author

@WorldSEnder I've created a PR: #2913

Again not sure how to request reviews from people / where I'm suppose to do that. Might be good to update the contributing.md with that? Or maybe I just missed it / don't know.

@WorldSEnder
Copy link
Member

The devs get a ping whenever a new PR is opened, so just give it some time for one of us to respond :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-yew-router Area: The yew-router crate documentation
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants