更改后重新渲染不可变的StencilJS道具

问题描述

我有以下具有三个属性的StencilJS组件。

import { Component,h,Prop } from "@stencil/core";

@Component({
  tag: 'twl-button',styleUrls: ['../style-tw.dist.css','./twl-button.scss'],scoped: true
})
export class ButtonComponent {

  @Prop() isBoolean: boolean = false;
  @Prop() aNumber: number = -1;
  @Prop() aString: string = "a"

  componentwillLoad() {
    alert(`componentwillLoad: ${this.isBoolean} | ${this.aNumber} | ${this.aString}`)
  }

  render() {
    alert(`rendering: ${this.isBoolean} | ${this.aNumber} | ${this.aString}`)
    return (
      <button onClick={() => this.didClick()}class={'w-1/3 self-center flex justify-center mt-1/12 py-2 px-2 border border-transparent font-normal text-lg rounded-md text-white bg-nord9 hover:bg-nord14 focus:outline-none focus:border-nord9 focus:shadow-outline-gray active:bg-nord10 transition duration-150 ease-in-out'}>
        Click to Change
      </button>
    );
  }

  didClick(): void {
    this.isBoolean = !this.isBoolean;
    this.aNumber = this.aNumber+1;
    this.aString = this.aString+"b";
  }
}

它在JSX中用作: <twl-button isBoolean={true} aNumber={0} aString={"init-string"}></twl-button>

我对StencilJS文档的理解是这些属性是隐式不变的。我认为不可变的属性也意味着没有渲染,因为没有任何变化。但是,当我单击按钮时,值会更改并调用渲染。我的误会在哪里?

pacakge.json:

...
"@stencil/core": "^1.17.3","@stencil/router": "^1.0.1","@stencil/sass": "^1.3.2",...

解决方法

您可以将@Prop()装饰器本身视为在属性(在您的情况下为watchisBooleanaNumber)上创建aString,并且每次为其分配值时,watch对旧值和新值执行相等性检查(===),以确定该值是否已更改(因此是否重新渲染)。需要)。

如果您的道具是一个对象,并且在对象@Prop()上设置了一个值,您将不会看到相同的行为,因为即使其中一个值已更改,===引用也会返回{{1 }},因为对象引用保持不变

true