有人可以向我解释为什么SomeClass
构造函数getLoggerClass
方法返回undefined,但在onClick()
方法内它返回logger类?
class App extends React.Component {
constructor(props){
super(props)
this.getLoggerClass = this.getLoggerClass.bind(this)
}
render(){
return(
<div>
<LoggerClass ref={(c)=>{this.loggerClass = c}}/>
<SomeClass app={this} />
</div>
)
}
getLoggerClass(){
return this.loggerClass
}
}
class SomeClass extends React.Component {
constructor(props){
super(props)
this.loggerClass = this.props.app.getLoggerClass()
console.log(this.loggerClass)
this.onClick = this.onClick.bind(this)
}
render(){
return <button onClick={this.onClick}>click</button>
}
onClick(){
console.log(this.props.app.getLoggerClass().console)
}
}
class LoggerClass extends React.Component {
render(){
return <div></div>
}
console(v){
console.log(v)
}
test(){}
}
ReactDOM.render(<App />,document.getElementById('app'))
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="app"></div>
答案 0 :(得分:1)
这是罪魁祸首:
constructor(props){
super(props)
this.loggerClass = this.props.app.getLoggerClass()
console.log(this.loggerClass)
this.onClick = this.onClick.bind(this)
}
要了解问题,您必须了解,引用mdn,The constructor method is a special method for creating and initializing an object created within a class.
基本上,这个构造函数方法用于初始化,因此在类生命期间只调用一次。因此,当您的SomeClass
首次渲染时,调用constructor
方法并在其中定义:this.loggerClass as this.props.app.getLoggerClass()(请注意,您在init处立即调用了该函数所以发生的事情就是:
undefined
尝试不直接调用getLoggerClass方法但稍后调用它,你不需要绑定它,只需在SomeClass组件中声明一个只调用getLoggerClass方法的方法:
callGetLoggerClassFromProps() {
return this.props.app.getLoggerCLass()
}
这样你就可以给ref分配时间了。
答案 1 :(得分:1)
这是因为ref
节点上的LoggerClass
函数在constructor
运行SomeClass
时尚未执行。创建虚拟DOM时会执行constructor
,而当组件实际安装到真实DOM(more info about mounting here)时会执行ref
。以下是我认为您正在寻找的内容,以及SomeClass
的{{1}}中的相关代码:
componentDidMount
class App extends React.Component {
constructor(props){
super(props)
this.getLoggerClass = this.getLoggerClass.bind(this)
}
render(){
return(
<div>
<LoggerClass ref={(c)=>{this.loggerClass = c}}/>
<SomeClass app={this} />
</div>
)
}
getLoggerClass(){
return this.loggerClass
}
}
class SomeClass extends React.Component {
constructor(props){
super(props)
this.onClick = this.onClick.bind(this)
}
componentDidMount() {
this.loggerClass = this.props.app.getLoggerClass()
console.log('in mounted', this.loggerClass.console)
}
render(){
return <button onClick={this.onClick}>click</button>
}
onClick(){
console.log(this.props.app.getLoggerClass().console)
}
}
class LoggerClass extends React.Component {
render(){
return <div></div>
}
console(v){
console.log(v)
}
test(){}
}
ReactDOM.render(<App />,document.getElementById('app'))