Stencil JS组件问题:内部方法为何无法访问类变量?
Stencil JS组件点击按钮时searchText输出undefined的原因及解决方法
在以下Stencil JS组件代码中,输入框输入内容时handleSearchTextChanged方法可正常为searchText赋值并打印,但点击Search按钮调用searchButtonClicked()方法时,控制台输出undefined,请问这是什么原因?
import { Component, h } from '@stencil/core'; import { faMagnifyingGlass, faX } from '@fortawesome/free-solid-svg-icons'; @Component({ tag: 'search', styleUrl: 'search.scss', shadow: true, }) export class Search { private searchText: string; handleSearchTextChanged(event) { this.searchText = event.target.value; console.log(event.target.value); console.log(this.searchText); } searchButtonClicked() { console.log(this.searchText); } render() { return ( <div class="container"> <h2>Find a Charity</h2> <div class="search-box"> <svg xmlns="http://www.w3.org/2000/svg" class="icon" viewBox="0 0 512 512"> <path d={faMagnifyingGlass.icon[4].toString()} /> </svg> <input type="text" placeholder="Search" onInput={(event) => this.handleSearchTextChanged(event)}/> <svg xmlns="http://www.w3.org/2000/svg" class="icon" viewBox="0 0 512 512"> <path d={faX.icon[4].toString()} /> </svg> </div> <button onClick={this.searchButtonClicked}>Search</button> </div> ); } }
核心原因:this的上下文绑定问题
- 输入框的
onInput使用了箭头函数包裹:(event) => this.handleSearchTextChanged(event),箭头函数不会创建自己的this,它的this继承自外层render方法的上下文(即组件实例),所以handleSearchTextChanged中能正常访问this.searchText。 - 按钮的
onClick直接传递函数引用:this.searchButtonClicked,当按钮触发点击事件时,this的上下文会切换为触发事件的按钮元素,而非组件实例,此时this.searchText无法找到对应属性,输出undefined。
解决方法
方法1:用箭头函数包裹按钮点击事件
修改按钮的onClick为箭头函数,确保this指向组件实例:
<button onClick={() => this.searchButtonClicked()}>Search</button>
方法2:用属性初始化器绑定函数上下文
将searchButtonClicked定义为箭头函数,永久绑定组件实例的this:
searchButtonClicked = () => { console.log(this.searchText); }
之后按钮的onClick可保持原写法:onClick={this.searchButtonClicked}
方法3:使用bind绑定this
在render中通过bind强制将函数的this绑定为组件实例:
<button onClick={this.searchButtonClicked.bind(this)}>Search</button>
注意:此方式每次render都会创建新的函数引用,性能略逊于前两种,不推荐在频繁重渲染的组件中使用。
内容的提问来源于stack exchange,提问作者Ali Hejazi
相关产品推荐
相关产品推荐

