问题描述
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()
装饰器本身视为在属性(在您的情况下为watch
,isBoolean
,aNumber
)上创建aString
,并且每次为其分配值时,watch
对旧值和新值执行相等性检查(===
),以确定该值是否已更改(因此是否重新渲染)。需要)。
如果您的道具是一个对象,并且在对象@Prop()
上设置了一个值,您将不会看到相同的行为,因为即使其中一个值已更改,===
引用也会返回{{1 }},因为对象引用保持不变
true