通过 ref 访问自定义组件方法无法按预期工作



有人可以向我解释为什么在构造函数SomeClassgetLoggerClass方法返回未定义,但在方法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>

这是因为在运行SomeClassconstructor时,LoggerClass节点上的ref函数尚未执行。constructor在创建虚拟 DOM 时执行,而ref在组件实际挂载到真实 DOM 时执行(有关挂载的更多信息,请单击此处(。以下是我认为您正在寻找的内容,以及SomeClasscomponentDidMount中的相关代码:

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()
} 

这样,您就可以为要分配的引用提供时间。

最新更新