Search code examples
javascriptreactjsrefsreact-forwardref

Forward Ref giving value of current as null


I am trying to implement forward Ref in my Demo Project but I am facing one issue. The value of current coming from forward ref is null, but once I re-render my NavBar component (by sending a prop) I get the value of current.

I basically need to scroll down to my Section present in Home Component from NavBar Component. It can be done by directly by giving a href attribute and passing the id. But I wanted to learn how forward ref works and hence this approach.

Can someone please help me with this?

Here is my Code.

import './App.css';
import NavBar from './components/NavBar/NavBar';
import Home from './components/Home/Home';

class App extends Component {

  constructor(props) {
    super(props);
    this.homeRefService = React.createRef();
    this.homeRefContact = React.createRef();
  }

  render() {
    return (
      <div className="App">
        <NavBar name={this.state.name} homeRef={{homeRefService: this.homeRefService , homeRefContact: this.homeRefContact}}/>
        <Home ref={{homeRefService: this.homeRefService, homeRefContact: this.homeRefContact }}/>
      </div>
    );
  }
    
}

export default App;



**Home Component**
import React from 'react';

const home = React.forwardRef((props , ref) => {
    const { homeRefService , homeRefContact  } = ref;

    console.log(ref);
  
    return (
        <div>
            <section ref={homeRefService} id="Services">
                Our Services
            </section>

            <section ref={homeRefContact} id="Contact">
                Contact Us
            </section>
        </div>
    )
})

export default home


**NavBar Component**

import React, { Component } from 'react'

export class NavBar extends Component {


    render() {

        let homeRefs =  this.props.homeRef;

        let homeRefServiceId;
        let homeRefContactId;

        if(homeRefs.homeRefService.current) {
            homeRefServiceId = homeRefs.homeRefService.current.id;
        }
        if(homeRefs.homeRefContact.current ) {
            homeRefContactId = homeRefs.homeRefContact.current.id;
        }
        
        return (
            <div>
                <a  href={'#' + homeRefServiceId}> Our Services</a> 
                <a  href={'#' + homeRefContactId }>Contact Us</a>
            </div>
        )
    }
}

export default NavBar

Solution

  • The ref is only accessible when the component got mounted to the DOM. So you might want to access the DOM element in componentDidMount.I suggest you to lift the state up to the parent component.
    Demo

    // App
    class App extends React.Component {
      constructor(props) {
        super(props);
        this.homeRefService = React.createRef();
        this.homeRefContact = React.createRef();
        this.state = { homeServiceId: "", homeContactId: "" };
      }
    
      componentDidMount() {
        this.setState({
          homeServiceId: this.homeRefService.current.id,
          homeContactId: this.homeRefContact.current.id
        });
      }
    
      render() {
        return (
          <div className="App">
            <NavBar
              homeServiceId={this.state.homeServiceId}
              homeContactId={this.state.homeContactId}
            />
            <Home
              ref={{
                homeRefService: this.homeRefService,
                homeRefContact: this.homeRefContact
              }}
            />
          </div>
        );
      }
    }
    
    // NavBar    
    export class NavBar extends Component {
      render() {
        return (
          <div>
            <a href={"#" + this.props.homeServiceId}> Our Services</a>
            <a href={"#" + this.props.homeContactId}>Contact Us</a>
          </div>
        );
      }
    }
    
    export default NavBar;