问题描述
我正在尝试在我的演示项目中实现前向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>
);
}
}