简体   繁体   中英

Parent refs are null when method is being called by child component - ReactJS

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://imgur.com/PrYRy0r

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!

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?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM