我想通过以下组件控制我的react-router:
import React from 'react';
export interface INavigationMenuProps{
routes: string[];
}
export class NavigationMenu extends React.Component<INavigationMenuProps> {
constructor(props: INavigationMenuProps) {
super(props);
}
handleButtonClick(path: string) : void {
//this.props.history.replace(path);
console.log(path);
}
render() {
let self = this;
return (
<div>
{
this.props.routes.map(function(item,id) {
let buttonText = item.replace('/','');
return <button key={id} onClick={ (e) => {self.handleButtonClick(item);}}>{buttonText}</button>
})
}
</div>
)
}
}
这确实有效。但是看着渲染功能让我思考这是否是一个合适的解决方案。我必须将this
安全地保存到变量,然后将lambda函数传递给按钮的on-click-handler,该按钮会调用我的this
变量的handleButtonClick-function。
这真的是处理事件的正确方法吗?
我也尝试过:
return <button key={id} onClick={this.handleButtonClick(item)}>{buttonText}</button>
但是这不起作用,因为onClick
与handleButtonClick
的签名不同
所以我不得不包装函数调用并尝试这样做:
return <button key={id} onClick={()=> {this.handleButtonClick(item);}}>{buttonText}</button>
但是随后出现以下错误:
'this'隐式具有类型'any',因为它没有类型 注释
答案 0 :(得分:2)
关于行let self = this;
,React代码库中最常见的方法是将这些函数绑定到组件的构造函数中。因此,您需要在构造函数的末尾添加一行如下代码:
this.handleButtonClick = this.handleButtonClick.bind(this);
在这种情况下,您不应遇到该“隐含任何”错误。该模式对于将功能绑定到组件的实例是必需的,这是您在运行时通过将this
分配给self
在render()中执行的操作。 / p>
要回答您的编号问题:
1.我的猜测是TypeScript能够解析变量的类型,但无法将this
解析为类NavigationMenu
的实例。
2.是的。此处的总体模式是正确的(在组件中编写单击处理程序以处理您可能需要的任何自定义逻辑)。我通常在React代码中看到这种情况,然后自己写React。您偏离我通常看到的地方的地方不是在构造函数中绑定函数。
答案 1 :(得分:1)
@ michael-langan的回答是正确的,但只是为了“完整”并提出另一种解决方案...您也可以采用这种方法(@tmeans在他的评论中暗示...):
import React from 'react';
export interface INavigationMenuProps{
routes: string[];
}
export class NavigationMenu extends React.Component<INavigationMenuProps> {
constructor(props: INavigationMenuProps) {
super(props);
}
handleButtonClick = (event: React.MouseEvent<HTMLButtonElement, MouseEvent>): void => {
const path = event.currentTarget.getAttribute('data-route');
console.log(path);
this.props.history.replace(path);
}
render() {
return (
<div>
{
this.props.routes.map((item, id) => {
let buttonText = item.replace('/','');
return <button key={id} data-route={item} onClick={this.handleButtonClick }>{buttonText}</button>
})
}
</div>
)
}
}
此方法的优点之一是,它避免在Component的点击处理程序内创建箭头函数,由于每次React渲染时都会“重新创建”此函数,因此有时可能会导致性能问题
此外,这避免了在构造函数中进行绑定,如果您在同一Component中有很多单击处理程序,则有时可能会造成阅读混乱。
但是,所有这些实际上都取决于首选项以及您严格遵循的规则。就像我说的那样,@ michael-langan的答案也完全正确。