Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React ref.current is null

Tags:

reactjs

ref

I'm working on an agenda/calendar app with a variable time range. To display a line for the current time and show blocks for appointments that have been made, I need to calculate how many pixels correspond with one minute inside the given time range.

So for example: If the agenda starts at 7 o'clock in the morning and ends at 5 o'clock in the afternoon, the total range is 10 hours. Let's say that the body of the calendar has a height of 1000 pixels. That means that every hour stands for 100 pixels and every minute for 1,66 pixels.

If the current time is 3 o'clock in the afternoon. We are 480 minutes from the start of the agenda. That means that the line to show the current time should be at 796,8 pixels (480 * 1,66) from the top of the calendar body.

No problems with the calculations but with getting the height of the agenda body. I was thinking to use a React Ref to get the height but I'm getting an error: ref.current is null

Below some code:

class Calendar extends Component {
    calendarBodyRef = React.createRef();

    displayCurrentTimeLine = () => {
        const bodyHeight = this.calendarBodyRef.current.clientHeight; // current is null
    }

    render() {
        return (
            <table>
                <thead>{this.displayHeader()}</thead>
                <tbody ref={this.calendarBodyRef}>
                    {this.displayBody()}
                    {this.displayCurrentTimeLine()}
                </tbody>
            </table>
        );
    }
}
like image 893
Thore Avatar asked Mar 19 '19 19:03

Thore


People also ask

Why is React ref current null?

A React ref most commonly returns undefined or null when we try to access its current property before its corresponding DOM element is rendered. To get around this, access the ref in the useEffect hook or when an event is triggered.

Why is useRef always null?

The "Object is possibly null" error is caused because the useRef() hook can be passed an initial value as an argument and we're passing it null as an initial value. The hook returns a mutable ref object whose . current property is initialized to the passed argument.

How will you access current value of a reference in React?

Accessing Refs current; The value of the ref differs depending on the type of the node: When the ref attribute is used on an HTML element, the ref created in the constructor with React. createRef() receives the underlying DOM element as its current property.

What is React createRef ()?

This method is used to access any DOM element in a component and it returns a mutable ref object which will be persisted as long as the component is placed in the DOM. If we pass a ref object to any DOM element, then the. current property to the corresponding DOM node elements will be added whenever the node changes.


3 Answers

So the thing about refs is that they aren't guaranteed to be set on first render. You can be sure they are set during and after componentDidMount so you have two ways going forward.

You could use the callback style ref and set state based on that. E.g. instead of passing your ref as the prop, you can pass in a reference to a function like this.handleRef and it would do some logic in there:

  handleRef = r => {     this.setState({ bodyHeight: r.clientHeight})     this.calendarBodyRef.current = r;   }; 

Or, you could keep your current set up but you would have to move your clientHeight bit to a lifecycle function like:

  componentDidMount() {     this.setState({ bodyHeight: this.calendarBodyRef.current.clientHeight });   } 

Ultimately, you can't immediately read the current value of a ref like that, you would have to check it after the render and then read your bodyHeight from state.

like image 105
Tom Finney Avatar answered Oct 14 '22 05:10

Tom Finney


You could use a ref callback function. In this case, you wouldn't need to use "React-createRef()".

<tbody ref={this.calendarBodyRef}>
...
calendarBodyRef = (e) => {
console.log(e)
}

You will get the DOM Element back and therefore don't need to use "current".

like image 34
Lukas Magerusan Avatar answered Oct 14 '22 04:10

Lukas Magerusan


If you are using react-redux and wrapped your component in connect function then you need to pass fourth argument i.e. forwardRef like this.

connect(mapStateToProps, mapDispatchToProps, null, {forwardRef: true})

I hope it will be helpful.

like image 20
Uddesh Jain Avatar answered Oct 14 '22 04:10

Uddesh Jain