Reputation: 549
I'm trying to call a method from a parent component inside of a child component in React. This is the code of my parent component:
import Video from 'Video/Video';
class CaseHeader extends React.Component {
constructor(props) {
super(props);
// Bind functions
this.videoComponentDidMount = this.videoComponentDidMount.bind(this);
}
videoComponentDidMount() {
console.log(this.caseheader);
}
render() {
let video = null;
if (this.props.caseData.title) {
video = <Video videoComponentDidMount={this.videoComponentDidMount} />;
}
return(
<div styleName="CaseHeader" ref={caseheader => this.caseheader = caseheader}>
{video}
</div>
);
}
}
export default CaseHeader;
So what I'm trying to do is this: my CaseHeader
component is rendering another component called Video
. I need to wait for this component to finish rendering to get his height. So I'm passing a method to the Video
which will be called in the componentDidMount
method. When the method is called I know the Video
component is rendered and I can get its offsetHeight. This is the code of the Video
component:
class Video extends React.Component {
constructor(props) {
super(props);
}
componentDidMount() {
this.props.videoComponentDidMount();
}
render() {
return(
<div styleName="Video" ref={video => this.video = video}></div>
);
}
}
export default Video;
So I expect the console.log(this.caseheader)
statement to log the DOM element of the CaseHeader
. The problem is this doesn't happen, null
gets logged instead.
When I add a the following code the CaseHeader component:
componentDidMount() {
console.log(this.caseheader);
}
The componentDidMount
method logs the right value but the videoComponentDidMount
method doesn't. This is a screenshot of what I'm talking about: https://i.sstatic.net/fr0ti.jpg
So my question is: How can I make parent refs (this.caseheader
in this case) defined when the function is being called from a child component?
Thank you in advance!
EDIT
Thanks to the help here I solved this issue by using the state of the CaseHeader
. What I did was update the constructor and added one method:
constructor(props) {
super(props);
// Set initial state
this.state = {
videoIsActive: false
};
// Bind functions
this.handleStateChange = this.handleStateChange.bind(this);
}
handleStateChange(state) {
this.setState(state);
}
So here I keep track off the video is active. I also pass the handleStateChange
method to the Video
component:
video = <Video updateParentState={this.handleStateChange} />;
In the Video
component I added the following:
this.props.updateParentState({videoIsActive: true});
This calls the following code in the CaseHeader
:
componentDidUpdate() {
if (this.state.videoIsActive) {
this.setCaseheaderBackgroundHeight();
}
}
Thanks guys!
Upvotes: 0
Views: 1244
Reputation: 1761
Why don't you set that offsetHeight of Video using setState in the caseHeader? So in the componentDidMount of Video class pass the offsetHeight value to the parent Component and in the CaseHeader videoComponentDidMount use that value to set state. Then access the offsetHeight property by calling this.state.offsetHeight?
Upvotes: 1