8

I want to use ref, however I am not able to use this in the conditional rendering which is initially false.

constructor(props) {
    super(props);
    this.state = { 
      filterActive: false,
    }
    this.firstRef = React.createRef();

}

If I use ref in this :-

{this.state.filterActive ?
    <label ref={this.firstRef}>Time Range</label>
:null}

The ref is null.

5
  • Not an answer, but you can rewrite your code as {this.state.filterActive && <label ref={this.firstRef}>Time Range</label>} - no need for the ternary operator returning null if false. Commented Sep 25, 2019 at 9:24
  • Hi @JamesWhiteley many thanks for your help. Actually this is just a dummy. I have a full section which needs to be rendered conditionally. Inside that section there are many elements and I want to use ref in one of those element. Commented Sep 25, 2019 at 9:27
  • When are you making filterActive state to true? Please share that code also. Commented Sep 25, 2019 at 9:27
  • on click of a button @RinkeshGolwala Commented Sep 25, 2019 at 9:28
  • Please share the complete component. Commented Sep 25, 2019 at 9:29

3 Answers 3

4

How about something Like this:

// directly assign the element to this.firstRef
// instead of doing it in the constructor
    <label
      ref={(elem) => (this.firstRef = elem)}
      style={{display: this.state.filterActive ? 'inline-block' : 'none'}}
    >
      Time Range
    </label>

and when using this.firstRef you put you work inside an if like this:

if (this.firstRef) {
// your work
}
Sign up to request clarification or add additional context in comments.

5 Comments

There are more elements which I can not show without condition is true, this is just an example. If I hide with css anybody will change the css and see those elements.
A normal user wouldn't have any idea about css. Wouldn't even know that you hid your element with css.
Anyways in order to get the element's ref the it has to be rendered. Therefore, I suggested to hid it with css.
Yes, but I can not do this with css.
Do you need the ref to do its work after or before the element renders?
1

I was facing the same problem but I'm using hooks. I found an alternate solution. By using Intersection Observer, we can solve it.

In Hooks, use 'useInView' hook from 'react-intersection-oberserver',

// Use object destructing, so you don't need to remember the exact order

const { ref, inView, entry } = useInView(options);

// Or array destructing, making it easy to customize the field names

const [ref, inView, entry] = useInView(options);

Attach 'ref' to your DOM node, 'inView' will return a boolean whether your DOM node is in View or not and 'entry' will give access to DOM node properties.

import React from 'react';
import { useInView } from 'react-intersection-observer';
 
const Component = () => {
  const { ref, inView, entry } = useInView({
    /* Optional options */
    threshold: 0,
  });
 
  return (
    <div ref={ref}>
      <h2>{`Header inside viewport ${inView}.`}</h2>
    </div>
  );
};

This fixed my problem.

For class based components, read here: https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API

Comments

-1

try this,

render(){
 return(
{this.state.filterActive ? (<label ref={this.firstRef}>Time Range</label>) : (null)}
)}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.