user image

Joseph Morgan
Published in : 2021-12-02

[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?

web-brackets.com

Comments

Mohamed Atef Date : 2021-12-02

Best answers

46

Best answers

46

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

Joseph Morgan Date : 2021-12-02

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

Leave a comment

Join us

Join our community and get the chance to solve your code issues & share your opinion with us

Sign up Now

Related posts

Module not found: Can't resolve 'swiper' in Reactjs [Solved]
Publish date: 2021-10-03 | Comments: 1

Tag: React js

Reload browser window using Reactjs?
Publish date: 2022-02-08 | Comments: 4

Tag: React js

[solved] useEffect is repeating the request Reactjs
Publish date: 2022-04-07 | Comments: 2

Tag: React js

Best way to update the state in one class component from the redux store?
Publish date: 2022-03-30 | Comments: 3

Tag: React js

npm install @mui/material returns error
Publish date: 2022-04-02 | Comments: 1

Tag: React js

TypeError: Super expression must either be null or a function
Publish date: 2022-03-13 | Comments: 2

Tag: React js