Deprecation warning using this.refs

I have a React component and I want to toggle a css class when clicked.

So I have this:

export class myComponent extends React.Component {
  constructor() {
    super();
    this.state = { clicked: false };
    this.handleClick = this.handleClick.bind(this);
  }

  render() {
    return (
      <div>
        <div onClick={this.clicked}><span ref="btn" className="glyphicon">&nbsp;</span></div>
      </div>
    );
  }

  handleClick() {
    this.refs.btn.classList.toggle('active');
  }

  componentDidMount() {
    this.refs.btn.addEventListener('click', this.handleClick);
    this.setState({
      clicked: this.state.clicked = true,
    });
  }

  componentWillUnmount() {
    this.refs.btn.removeEventListener('click', this.handleClick);
    this.setState({
      clicked: this.state.clicked = false,
    });
  }
}

This problem is that ESLint keeps telling me "this.refs" is depreciated.

What do I do instead? How can I fix it so it's not using depreciated code?


The Lint rule you are referring to is called no-string-refs and warns you with:

"Using string literals in ref attributes is deprecated (react/no-string-refs)"

You are getting this warning because have implemented the deprecated way of using refs (by using strings). Depending on your React version, you can do:

React 16.3 and later
constructor() {
  super();
  this.btnRef= React.createRef();
  this.state = { clicked: false };
  this.handleClick = this.handleClick.bind(this);
}

render() {
  return (
    <div>
      <div onClick={this.addVote}><span ref={this.btnRef} className="glyphicon">&nbsp;</span></div>
    </div>
  );
}

React 16.2 and older
constructor() {
  super();
  this.btnRef;  //not necessary to declare the variable here, but I like to make it more visible.
  this.state = { clicked: false };
  this.handleClick = this.handleClick.bind(this);
}

render() {
  return (
    <div>
      <div onClick={this.addVote}><span ref={(el) => this.btnRef = el} className="glyphicon">&nbsp;</span></div>
    </div>
  );
}

For even better readability, you could also do:

render() {
  let myRef = (el) => this.btnRef = el;
  return (
    <div>
      <div onClick={this.addVote}><span ref={myRef} className="glyphicon">&nbsp;</span></div>
    </div>
  );
}

Have a look at what the official documentation says on Refs and the DOM, and this section in particular:

Legacy API: String Refs

If you worked with React before, you might be familiar with an older API where the ref attribute is a string, like "textInput", and the DOM node is accessed as this.refs.textInput. We advise against it because string refs have some issues, are considered legacy, and are likely to be removed in one of the future releases. If you're currently using this.refs.textInput to access refs, we recommend the callback pattern instead.

javascript - Deprecation warning using this.refs, You are getting this warning because have implemented the deprecated way of using refs (by using strings). Depending on your React version, you can do:  @spences10 You either use a named ref, <Pararallax ref="parallax" and now within the containing class you can do this.refs.parallax and you'll get the instance of Parallax, which features the scrollTofunction. If your linter complains about it, use functional refs, which are encouraged by React i guess, it's all the same:


you can try a more declarative way. I changed your code to reflect this. You just need to remind that a component will refresh and call render in every state/props change. So, we can create the class of your element inside render method.

import React from 'react'

export default class myComponent extends React.Component {
  constructor() {
    super();
    this.state = { clicked: false };
    this.handleClick = this.handleClick.bind(this);
  }

  render() {
    let btnClass = 'glyphicon'
    if(this.state.clicked){
      btnClass+=' active'
    }
    return (
      <div>
        <div onClick={this.handleClick}><span ref="btn" className={btnClass}>&nbsp;</span></div>
      </div>
    );
  }

  handleClick() {
    this.setState({
      clicked: !this.state.clicked
    })
  }
}

Update refs element usage · Issue #88 · yahoo/react-stickynode , Update refs usage to new api and don't use string refs Can we please merge this PR as we have quite a few deprecation warnings on our apps due to this. Use React.createElement from the "react" package instead.' This deprecation warning was added in version 0.25 -- see release notes and the relevant commit . As of now, 0.25 is still labelled "pre-release", but it'll be the latest official version any day now, so these warnings will soon affect everyone using react-native-maps with the latest version of React Native.


The reason this ESLint rule exists is that string Refs are on their way out. However, for the code above I would recommend to not use a Ref in the first place.

Don't Overuse Refs

React's advantage is that it is declarative. Meaning, we have state and an expression (returned JSX) of how the UI (more precisely the DOM) should look given a certain state.

Whatever can be done using just state and UI expression, should be done this way. The problem with the use of a Ref in the code above is that it makes the code imperative. We can't understand how the DOM will look just from the JSX. Here is how you could achieve the same result in a declarative way:

export class myComponent extends React.Component {
    constructor(props) {
        super(props);
        this.state = { 
            active: false 
        };
    }

    handleClick = () => {  // with arrow function there is no need for binding. 
        this.setState(
            prevState => {
                return {
                    active: !prevState.active
                }
            }
        )
    }

    render() {
        return (
            <div>
                <span 
                    onClick={this.handleClick} 
                    className={`glyphicon ${this.state.active && "active"}`}
                >
                    Hello World
                </span>
            </div>
        );
    }

}

Refs should be used when state and UI expression aren't enough, and you need access to the actual DOM. For example, focusing on an input field, scrolling to an element, or getting the exact width and height of an element.

If you do use Refs, avoid string refs

String refs harm performance, aren't composable, and are on there way out.

string refs have some issues, are considered legacy, and are likely to be removed in one of the future releases. [Official React documentation]

[resource1][1], [resource2][1]

Option #1: Use React.createRef

class MyComponent extends Component {

    constructor(props) {
        super(props)
        this.myRef = React.createRef() // create a ref object 
    }

    render() {
        return <div ref={this.myRef}></div> // Attach the ref property to a dom element
    }

}

Option #2: Use a ref callback

class MyComponent extends Component {

    constructor(props){    // Optional, declare a class field
        super(props)
        this.myRef=null    
    }

    render() {
        return <div ref={ (ref) => this.myRef=ref }></div>
    }   // Attach the dom element to a class field

}

findDOMNode deprecation · Issue #14357 · facebook/react · GitHub, connect does properly forward their refs in the beta release of 6.x. React.​StrictMode throws warning because of `findDOMNode` use  I ran a Python program and got a DeprecationWarning, like:. D:\programs\anaconda2\lib\site-packages\sklearn\utils\deprecation.py:70: DeprecationWarning: Function log_multivariate_normal_density is deprecated; The function log_multivariate_normal_density is deprecated in 0.18 and will be removed in 0.20.


Strict Mode – React, I have a React component and I want to toggle a css class when clicked. So I have this: export class myComponent extends React.Component  you can use: javac FileName.java -Xlint:-deprecation. But then this will give you warnings and also tell you the part of the code that is causing deprecation or using deprecated API. Now either you can run your code with these warnings or make appropriate changes in the code.


React v16.13.0 – React Blog, Identifying components with unsafe lifecycles; Warning about legacy string ref API usage; Warning about deprecated findDOMNode usage; Detecting  When using import with esm using morgan, I get the following warning message : morgan deprecated default format: use combined format node_modules\esm\esm.js:1:277757 This does not occur when using require.


react this.refs deprecated Code Example, This release adds a new warning only for those cases in advance of the deprecation. For example, it will fire if you use String Refs together with  If you're using gridfs-stream, you'll see the below deprecation warning: DeprecationWarning: GridStore is deprecated, and will be removed in a future version. Please use GridFSBucket instead. That is because gridfs-stream relies on a deprecated MongoDB driver class. You should instead use the MongoDB driver's own streaming API.