将当前值设为空的正向引用

问题描述

我正在尝试在我的演示项目中实现前向Ref,但是我面临一个问题。来自正向ref的current的值为null,但是一旦我重新渲染NavBar组件(通过发送prop),我就获得current的值。

我基本上需要从NavBar Component向下滚动到Home Component中存在的Section。 可以直接通过提供href属性并传递ID来完成此操作。但是我想了解前向引用的工作原理以及这种方法

有人可以帮我吗?

这是我的代码

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

解决方法

仅当组件安装到DOM时才能访问引用。因此,您可能想访问componentDidMount中的DOM元素。建议您lift the state up到父组件。
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;
,

您所有的代码都可以使用。您可以在所有渲染后访问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>
        );
    }
}

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...