【发布时间】:2017-12-22 00:38:18
【问题描述】:
我正在开发名为 ProjectCard 的 React 组件,它包含两个 div。第二个 div 有一个下拉菜单,当用户将鼠标悬停在卡片上或单击下拉菜单时,我想突出显示整张卡片。我使用 Radium 为以前的组件添加悬停功能,但为了合并这个新的高亮逻辑,我在卡片状态下跟踪了 isActive 和 isLocked。例如,当鼠标进入或离开以下函数中的组件时,我切换isActive。 (我在构造函数中绑定了toggleActive)
toggleActive () {
console.log(this);
this.setState({
isActive: !this.state.isActive
});
}
但是,我收到一个错误,即在安装组件之前我无法设置状态。在各种功能中戳了一下并记录this,这似乎是镭的问题。我在导出中使用了 Radium 包装器,如下所示:export default Radium(ProjectCard);,上面的toggleActive 记录为ProjectCard 为this,而componentDidMount 记录为RadiumEnhancer(ProjectCard) 为this。无镭的解决方法是使用 HoC,但我想我可以通过调整绑定它的范围来解决这个问题,所以我将函数绑定移动到 componentDidMount,如下所示。 (使用箭头函数自动绑定范围,如来自构造函数的调用)
constructor (props: Props) {
super(props);
this.state = {
isActive: true,
isLocked: false
};
}
componentDidMount() {
console.log(this);
this.onClick = this.onClick.bind(this);
this.toggleLock = this.toggleLock.bind(this);
this.toggleActive = this.toggleActive.bind(this);
console.log("mounted, functions bound");
//console.log(this.toggleActive);
this.toggleActive();
//manual fix, stackoverflow this.
}
但是,在 componentDidMount 中绑定并将鼠标悬停在组件上不会导致任何更改,并且 toggleActive 将 this 记录为未定义。不走运,修复似乎不起作用。
但是,在尝试调试时,我手动调用了 toggleActive(如上所示),它记录了 RadiumEnhancer(ProjectCard)(我想要的范围),并且奇迹般地,悬停功能开始工作(并且其他函数也获得了正确的范围)。
我的问题是:
- 不正确的范围/镭是否导致了 setState 错误?代码中除了 setState 之外没有任何异步操作。
- 如果是这样,此修复是否合法?为什么我更改了绑定
this的范围后它不起作用? - 为什么手动调用toggleActive 会赋予所有函数正确的
this和范围?
谢谢! 这是相关代码的粘贴箱:https://pastebin.com/MRKw2APw
【问题讨论】:
-
尝试使用箭头函数定义
componentDidMount = () => {}这样componentDidMount将用作上下文this。 -
使用箭头表示法将其默认为未增强的 ProjectCard,因此不起作用,不过感谢您的建议!
标签: javascript reactjs ecmascript-6 radium