有人可以向我解释为什么在构造函数SomeClass
getLoggerClass
方法返回未定义,但在方法onClick()
内部它返回记录器类?
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>
这是因为在运行SomeClass
constructor
时,LoggerClass
节点上的ref
函数尚未执行。constructor
在创建虚拟 DOM 时执行,而ref
在组件实际挂载到真实 DOM 时执行(有关挂载的更多信息,请单击此处(。以下是我认为您正在寻找的内容,以及SomeClass
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'))
<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>
这是罪魁祸首:
constructor(props){
super(props)
this.loggerClass = this.props.app.getLoggerClass()
console.log(this.loggerClass)
this.onClick = this.onClick.bind(this)
}
要理解这个问题,你必须理解,引用mdn,构造函数方法是一种特殊的方法,用于创建和初始化在类中创建的对象。
所以基本上,这个构造函数方法用于初始化,因此在类生命周期中只调用一次。因此,当您的SomeClass
首次渲染时,将调用constructor
方法,并在其中将 :this.loggerClass 定义为 this.props.app.getLoggerClass(((请注意,您在 init 时立即调用了该函数(,因此正在发生的事情是:
- 第一个构造函数((被调用
- 在其中,您直接调用了getLoggerClass((方法,此方法返回dom节点,但在初始化时它是
undefined
尽量不要直接调用getLoggerClass方法,但稍后调用它,你不需要绑定它,只需在你的SomeClass组件中声明一个只调用getLoggerClass方法的方法,如下所示:
callGetLoggerClassFromProps() {
return this.props.app.getLoggerCLass()
}
这样,您就可以为要分配的引用提供时间。