this.refs.something returns "undefined"
Asked Answered
A

6

52

I have an element with a ref that is defined and ends up getting rendered into the page :

    <div ref="russian" ...>
       ...
    </div>

I want to access the DOM element properties like offset... or something. However, I keep getting undefined and I haven't the faintest idea why. After some searching it's clear that refs are only applicable to one file but I'm not using this anywhere besides this one page. I'm saying this to log it:

console.log('REFS', this.refs.russian);

What could be causing this?

Anacoluthia answered 5/2, 2016 at 17:26 Comment(5)
this.refs would be the string "russian" (assuming you're in the right scope), not an object, so it wouldn't have a property of "russian"Hinayana
@Pamblam in reactjs ref is a reference to an element dom. It becomes accessible as an objectPanta
Also it would help to see more code. Ref is only accessible to the object it binds to. In most cases you would have to bind it to element that its coming fromPanta
ref is not traditional scope binding, it's owner-ownee relationship.Camilia
What version of React? Prior to 14, you had to use refs.getDOMNode() IIRCLachrymal
U
36

The correct place to work with refs is inside specific React lifecycle methods e.g. ComponentDidMount, ComponentDidUpdate

You cannot reference refs from the render() method. Read more about the cautions of working with refs here.

If you move your console.log('REFS', this.refs.russian); call to ComponentDidMount or ComponentDidUpdate lifecycle methods (assuming you are on React >= 14) you should not get undefined as a result.

UPDATE: also refs will not work on stateless components per the caution link above

Unicuspid answered 10/2, 2016 at 1:37 Comment(0)
C
44

Check that you are not accessing ref before the child component has been mounted. E.g. it doesn't work in componentWillMount. A different pattern which auto invokes ref related callback after the element has been mounted is this-

<div ref={(elem)=>(console.log(elem))}/>

You can use this notation to get mounted elements in deep nesting as well -

<div ref={this.props.onMounted}/>
Camilia answered 5/2, 2016 at 17:45 Comment(0)
U
36

The correct place to work with refs is inside specific React lifecycle methods e.g. ComponentDidMount, ComponentDidUpdate

You cannot reference refs from the render() method. Read more about the cautions of working with refs here.

If you move your console.log('REFS', this.refs.russian); call to ComponentDidMount or ComponentDidUpdate lifecycle methods (assuming you are on React >= 14) you should not get undefined as a result.

UPDATE: also refs will not work on stateless components per the caution link above

Unicuspid answered 10/2, 2016 at 1:37 Comment(0)
T
9

Update since React version 16.4

In your constructor method define your ref like this

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

In your render where you are using ref do this.

<input
  name="russian"
  ref={this.russian} // Proper way to assign ref in react ver 16.4
/>  

For e.g if you want to have focus when component mounts do this

componentDidMount() {
  console.log(this.russian); 
  this.russian.current.focus();
 }

Reference Refs Documentation React

Timely answered 2/9, 2018 at 11:10 Comment(0)
I
0

I was having a similar issue in my form validation methods, trying to assign this.ref.current.reportValidity()

Writing the method I was doing this in as validate = () => {} instead of validate() {} helped me out, but I'm not totally sure why exactly, just something I remembered from habits I had in my past work experience that gave me this. Hope it helps and could someone kindly clarify this answer with why this might work exactly.

Invalidate answered 21/3, 2019 at 21:21 Comment(1)
use an arrow function to wrap around an event handler, This is equivalent to calling .bind(Binding methods helps ensure that the second snippet works the same way as the first one) When you need to invoke a function prop with an argument, you should always specify a fat arrow function that invokes the prop, React will evaluate the expression when the component renders its content, which will invoke the prop even though the user hasn’t clicked the button element. This is rarely the intended effect and can cause unexpected behaviors or produce an error.Escent
B
0

If you are exporting class withStyle, please remove and export default nomally.

Bowsprit answered 9/4, 2019 at 16:59 Comment(0)
W
0

Instead of putting your Console.log inside the function example(){...} you should put it inside:

example=()=>{....}
Warwick answered 10/1, 2020 at 9:45 Comment(1)
why do it this way?Averroism

© 2022 - 2024 — McMap. All rights reserved.