Forward Ref дает значение тока как ноль

Я пытаюсь реализовать переадресацию Ref в своем демонстрационном проекте, но столкнулся с одной проблемой. Значение тока, исходящего из прямой ссылки, равно нулю, но как только я повторно визуализирую свой компонент NavBar (отправив опору), я получаю значение тока.

Мне в основном нужно прокрутить вниз до моего раздела, присутствующего в домашнем компоненте, из компонента NavBar. Это можно сделать, напрямую задав атрибут href и передав идентификатор. Но я хотел узнать, как работает forward ref и, следовательно, этот подход.

Может кто-нибудь помочь мне с этим?

Вот мой код.

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

person Akhilesh Ojha    schedule 13.09.2020    source источник


Ответы (2)


Ссылка доступна только тогда, когда компонент смонтирован в DOM. Таким образом, вы можете получить доступ к элементу DOM в componentDidMount. Я предлагаю вам поднять состояние в родительский компонент.
Демо

// 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;
person dongnhan    schedule 13.09.2020

Весь ваш код будет в порядке. Вы можете получить доступ к ref после того, как все отрендерили.

Пример демонстрации, как это работает:

export class NavBar extends Component {


    render() {

        let homeRefs =  this.props.homeRef;

        console.log('from Nav Bar');
        console.log(this.props.homeRef.homeRefService);
        console.log('----');

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

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


    useEffect(() => {
        console.log('from home');
        console.log(homeRefService);
        console.log('----');

        props.showUpdate();
    })

    return (
        <div>
            <section ref={homeRefService} id="Services">
                Our Services
            </section>

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

class App extends Component {
    state = {
        name: 'init',
    }

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

    componentDidUpdate(prevProps, prevState, snapshot) {
        console.log('from app');
        console.log(this.homeRefService);
        console.log('----');
    }

    render() {
        return (
            <div className="App">
                <div>{this.state.name}</div>
                <NavBar name={this.state.name} homeRef={{homeRefService: this.homeRefService , homeRefContact: this.homeRefContact}}/>
                <Home showUpdate={() => this.state.name === 'init' && setTimeout(() => this.setState({name: 'UpdatedRef'}), 2000)} ref={{homeRefService: this.homeRefService, homeRefContact: this.homeRefContact }}/>
            </div>
        );
    }
}
person Viet Dinh    schedule 13.09.2020