0

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

我基本上需要从 NavBar 组件向下滚动到 Home 组件中的部分。可以通过直接提供 href 属性并传递 id 来完成。但我想了解 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
4

2 回答 2

1

仅当组件安装到 DOM 时才能访问 ref。所以你可能想访问 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;
于 2020-09-13T10:45:38.413 回答
1

你所有的代码都可以。您可以在所有渲染后访问 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>
        );
    }
}
于 2020-09-13T11:09:00.563 回答