最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How to use ref in (conditional render) - Stack Overflow

programmeradmin1浏览0评论

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.

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.

Share Improve this question asked Sep 25, 2019 at 9:22 Anup MishraAnup Mishra 1491 gold badge2 silver badges12 bronze badges 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. – James Whiteley 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. – Anup Mishra Commented Sep 25, 2019 at 9:27
  • When are you making filterActive state to true? Please share that code also. – Rinkesh Golwala Commented Sep 25, 2019 at 9:27
  • on click of a button @RinkeshGolwala – Anup Mishra Commented Sep 25, 2019 at 9:28
  • Please share the plete ponent. – Rinkesh Golwala Commented Sep 25, 2019 at 9:29
Add a ment  | 

3 Answers 3

Reset to default 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
}

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 ponents, read here: https://developer.mozilla/en-US/docs/Web/API/Intersection_Observer_API

try this,

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

评论列表(0)

  1. 暂无评论