问题大致总结在代码段中的注释中。当我在this._setSize
中绑定constructor
时,它永远不会知道this.container
- 即使在componentDidMount
中调用时也是如此。我究竟做错了什么?谢谢!
export default class MyComponent extends React.Component {
constructor () {
super()
this._setSize = this._setSize.bind(this)
}
componentDidMount () {
const container = this.container // <div></div> :)
this._setSize()
window.addEventListener('resize', this._setSize)
}
componentWillUnmount () {
window.addEventListener('resize', this._setSize)
}
_setSize () {
const container = this.container // undefined :(
const containerSize = {
x: container.offsetWidth,
y: container.offsetHeight
}
this.setState({ containerSize })
}
render () {
return (
<div ref={node => this.container = node}>
</div>
)
}
}
答案 0 :(得分:4)
在每次重新渲染中,您正在创建并传递新的函数实例以设置容器引用。然后使用null
调用上一个函数。因此,您可能会意外地将this.container
设置为null
:
<div ref={node => this.container = node}>
当您在此处传递组件实例方法而不是内联函数时,它会在引用时调用一次,在组件卸载期间第二次调用null
。 E.g:
// dont forget to bind it in constructor
onContainerRef (node) {
// furthermore you can even check if node is not null
// if (node) { ...
this.container = node
}
// ... in render
<div ref={this.onContainerRef}>
您可以在docs中阅读更多内容。
答案 1 :(得分:1)
我已修复您的代码,现在正在运行:see working DEMO
问题是什么?
componentWillUnmount () {
window.addEventListener('resize', this._setSize)
}
您没有从window
移除事件监听器,因为在componentWillUnmount
中您有addEventListener
而不是removeEventListener
。如果您对组件进行了任何条件渲染,则还会调用resize
事件_setSize
。
要说明此问题,请使用破解的演示并点击Toggle
按钮并查看输出:see broken DEMO