Skip to content

Instantly share code, notes, and snippets.

@andyjessop
Last active January 26, 2024 22:46
Show Gist options
  • Save andyjessop/8568b6a85e24deea15f98fabddc0e8c4 to your computer and use it in GitHub Desktop.
Save andyjessop/8568b6a85e24deea15f98fabddc0e8c4 to your computer and use it in GitHub Desktop.
Link custom element to handle route changes in thepassle/app-tools router
import { RouterLink } from './RouterLink';
// After router is setup...
RouterLink.setRouter(() => router);
import { css, html, LitElement } from 'lit';
import { customElement, property } from 'lit/decorators.js';
import { Item } from './types';
@customElement('my-links')
export class Links extends LitElement {
@property({ type: Array })
items: Item[] = [];
static styles = [
css`
cx-link::part(link):hover {
background-color: var(--color-gray-100);
}
cx-link::part(link active) {
background-color: var(--color-primary-500);
color: white;
}
cx-link::part(link active):hover {
background-color: var(--color-primary-500);
cursor: default;
}
`,
];
render() {
return html`
<ul>
${this.items.map(
(item) => html`
<li>
<cx-link to="${item.path}">${item.title}</cx-link>
</li>
`,
)}
</ul>
`;
}
}
@KonnorRogers
Copy link

Not that you asked for a review, but these lines actually introduce a memory leak and can cause the page the navigation handlers to fire many times:

https://gist.github.com/andyjessop/8568b6a85e24deea15f98fabddc0e8c4#file-routerlink-ts-L54-L57

https://gist.github.com/andyjessop/8568b6a85e24deea15f98fabddc0e8c4#file-routerlink-ts-L43-L46

    RouterLink.router.addEventListener(
      'route-changed',
      this.handleRouteChange.bind(this),
    );

The .bind() creates a new function everytime, so it will never have a stable reference to dedupe new listeners, or be able to remove listeners.

The "easy" fix is something like this:

constructor () {
  super()
  this.boundHandleRouteChange = this.handleRouteChange.bind(this)
}

connectedCallback () {
 RouterLink.router.addEventListener("route-change", this.boundHandleRouteChange)
}

disconnectedCallback () {
 RouterLink.router.removeEventListener("route-change", this.boundHandleRouteChange)
}

@andyjessop
Copy link
Author

Amazing, thank you!

@andyjessop
Copy link
Author

I've updated the gist and tested locally, and it looks good 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment