3

I am creating my personal website/blog as a a single page application using Mithril.js. All pages and blog posts on my website are rendered using Page and Post components, and the correct page is loaded based on the :slug in the URL.

The problem I have is that whenever I try and switch between pages, the content of the page does not update. Switching between pages and posts works because I am alternating between Page and Post components. But when I try and use the same component twice in a row, going from page to page, it doesn't update the webpage.

m.route(document.body, '/', {
  // `Home` is a wrapper around `Page`
  // so I can route to `/` instead of `/home`
  '/': Home,
  '/:slug': Page,
  '/blog/:slug': Post
});
const Home = {
  view() {
    return m(Page, { slug: 'home' });
  }
};

Here is the Page component (the Post component is very similar). Both components render correctly.

const Page = {
  content: {},
  oninit(vnode) {
    m.request({
      method: 'GET',
      url: 'content.json',
    }).then((response) => {
      Page.content = response.pages[vnode.attrs.slug];
    });
  },
  view() {
    if (Page.content) {
      return [
        m('#content', m.trust(Page.content.body))
      ];
    }
  }
};

Why isn't Mithril recognizing that the slug changed?

evanrelf
  • 303
  • 3
  • 12

1 Answers1

1

The docs page for m.route has a solution for you.

When a user navigates from a parameterized route to the same route with a different parameter (e.g. going from /page/1 to /page/2 given a route /page/:id, the component would not be recreated from scratch since both routes resolve to the same component, and thus result in a virtual dom in-place diff. This has the side-effect of triggering the onupdate hook, rather than oninit/oncreate. However, it's relatively common for a developer to want to synchronize the recreation of the component to the route change event.

Tivac
  • 2,553
  • 18
  • 21