简体   繁体   中英

How to rerender component on variable change which is imported from a helper script?

I have something like the code below and I would like to check with you if there is a better way to do this. Basically I have a helper script which gets data from a third party API. I would like the components that import this helper script to rerender every time the API is called. The API is called multiple times.

I'm doing this right now:

MyClass script:

import { rerenderComponentList } from '../../../helpers/myscript';

export default class MyClass extends LitElement {
  static get properties() {
    return {
      item: {},
    };
  }

  constructor() {
    super();
    this.item = [];

    rerenderComponentList(this);
  }

  render() {
    const icon = Iconify.renderSVG(this.item.icon, {});

    return html` <div>Hello</div> `;
  }

  static get styles() {
    return styles;
  }
}

The rerenderComponentList imported function is used to send the current element object to the helper script.

Helper script:

const list = [];

export function rerenderComponentList(object) {
  list.push(object);
}

function rerenderComponent() {
  list.map((item) => item.requestUpdate());
}

function callbackIcons(loaded) {
  if (loaded.length) {
    rerenderComponent();
  }
}

//Function used to call API in app.js
export function loadIcons(icons) {
  API.myfunction(icons, callbackIcons);
}

The rerenderComponent function is used to call the requestUpdate on each element object.

Any better and nicer suggestions would be greatly appreciated!

This is where the new ReactiveController can help. This lets you hook in to the component lifecycle, so your API can tell the LitElement when it needs to render:

import { ReactiveController, ReactiveControllerHost } from 'lit';

export class MyController 
    implements ReactiveController {

    list = [];

    constructor(private host: ReactiveControllerHost) {
        host.addController(this);
    }

    private callbackIcons(loaded) {
        this.list = loaded;
        this.host.requestUpdate();
    }
    
    loadIcons(icons) {
        API.myfunction(icons, items => this.callbackIcons(items));
    }
}

Then in your element:

import { LitElement, html } from 'lit';
import { customElement } from 'lit/decorators.js';
import { MyController } from './my-controller.js';

@customElement('my-element')
class MyElement 
    extends LitElement {

    private myController = new MyController(this);

    render() {
        const icons = this.myController.list.map(i => Iconify.renderSVG(i)) ;
        return html`... ${icons} ...`;
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM