user

Joseph Morgan

2 Dec 2021

[Solved] Cannot read properties of null (reading 'getBoundingClientRect')

React js

TypeError: Cannot read properties of null (reading 'getBoundingClientRect') in Reactjs , I am facing this issue when I am trying to use the function on a Ref on router change for example I want to scroll down for a specific element when the Hash added to the link, so I am using a function called history.listen and scrolling down is using body.scrollTo and I am getting the position of the element in the using this.myRef.current.getBoundingClientRect() but the issue that sometimes when i move between pages and then come back to that page and add the hash I get this issue which is attached in the screenshot below, 
the code is 

import React from 'react';
import { withRouter } from 'react-router-dom';
import { 
 Box,
 Container,
 Typography,
 withStyles,
} from '@material-ui/core';
import About from './About';
import Locations from './Locations';

const styles = (theme) => ({
 root:{

 },
 breadcrumbs:{
 padding: '15px 0px 18px 0px',
 },
 link:{
 textTransform: 'uppercase',
 color: theme.palette.text.primary,

 },
 lockContainer:{
 backgroundColor: 'rgba(0, 0, 0, 0.2)',
 display: 'flex',
 alignItems: 'center',
 justifyContent: 'center',
 [theme.breakpoints.up('md')]:{
 minHeight: '300px',
 width: '100%'
 },
 [theme.breakpoints.down('md')]:{
 minHeight: '200px',
 },
 borderRadius: '15px'
 },

});

class Details extends React.Component {

 state = {
 currentTab: 0,
 tabs: [],
 scrollTopVal: 0,
 };

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

 scrollTo = (id) => {
 // console.log(id);
 let headerOffset = this.props.headerHeight+64;
 let body = window.document.getElementById('main-Content');
 var elementPosition = null;
 if(id === '#about'){
 elementPosition = this.myRef.current.getBoundingClientRect().top - headerOffset + this.state.scrollTopVal;
 if (!elementPosition) return false;
 console.log(elementPosition);
 return body.scrollTo({
 top: elementPosition,
 behavior: "smooth"
 });
 }
 }

 isInViewportRef(el, offset = -100) {
 if (!el) return false;
 const top = el?.getBoundingClientRect().top - (this.props.headerHeight+64);
 // console.log(top);
 if(top < 50 && top >= 0){
 return true;
 }else{
 return false;
 }
 }

 componentDidMount(){
 this.props.history.listen((location) => {
 if(location.hash){
 this.scrollTo(location.hash);
 }
 });
 }

 render(){
 const { classes } = this.props;

 return(
 <div style={{backgroundColor: '#fff'}}>
 {/* Start of Content */}
 <Container maxWidth="lg">
 {
 this.props.company?
 <div ref={this.myRef}>
 <Box mt={6}>
 <About company={this.props.company} />
 </Box>
 </div>
 : null
 }
 {
 <Box mt={2}>
 {
 this.props.company.subscription === 0?
 <div ref={this.myRef1}>
 <Box>
 <Typography variant="h3" style={{ fontWeight: '600' }} color="textPrimary">
 Locations 
 </Typography>
 <Box className={classes.lockContainer} mt={3}> 
 <img src="/static/Lock.png" style={{ maxWidth: '100%' }} alt="lock"/>
 </Box>
 </Box>
 </div>
 :
 this.props.company.associations || this.props.company.locations?
 <div ref={this.myRef1}>
 <Locations company={this.props.company} />
 </div>
 :
 <Box py={5}>
 <div ref={this.myRef1}>
 <Typography variant="h3" style={{ fontWeight: '600' }} color="textPrimary">
 Locations 
 </Typography>
 <Typography variant="h5" style={{ textAlign: 'center', paddingBottom: '30px' }}>
 Information is not provided by this vendor
 </Typography>
 </div>
 </Box>
 }
 </Box>
 }
 {/* <RatingInformation /> */}
 {/* <RattingCustomerService /> */}
 </Container>
 {/* End of Content */}
 </div>
 );
 }
}
export default withRouter(withStyles(styles)(Details));

Anyone can help please?

Comments

Mohamed Atef

2 Dec 2021

Best Answer

best answer
githubgithubgithub

Hello there,
there is one step you can do so when the router change & the section Ref is null, it will not apply the function of scrolling down until there is a value of the Refs, 
this gonna be by adding a condition before the scrolling function so this.myRef should contain a value to execute the function 

 this.props.history.listen((location) => {
 if(location.hash){
 if(!this.myRef.current){
 return null;
 }
 this.scrollTo(location.hash);
 }
 });

Good luck :)

Replies

Joseph Morgan

2 Dec 2021

Cannot Believe it's WORKING !!
Thank you man, you are awesome 

© 2024 Copyrights reserved for web-brackets.com