3

I am trying to catch an element using an ID in React, but I could not.

render() {
  //Looping through all menus
  let menuOptions = this.props.menuLists.map(menuList => {
    return (
      <li className="nav-item active" key={menuList.name}>
        <a className="nav-link" href={menuList.anchorLink}>
          {menuList.name}
        </a>
      </li>
    );
  });

  return (
    <React.Fragment>
      <div id="animSec">
        <canvas id="myCanvas" />
      </div>
    </React.Fragment>
  );
}

I want to call the myCanvas ID.

I tried by this.refs, but it's sent me undefined. I also tried react-dom:

ReactDOM.findDOMNode(this.refs.myCanvas);

but get nothing. I call findDOMNode on the constructor first and I tried componentDidMount but get nothing.

sayalok
  • 882
  • 3
  • 15
  • 30
  • Possible Duplicate of [How to access a DOM element in React? What is the equilvalent of document.getElementById() in React](https://stackoverflow.com/questions/38093760/how-to-access-a-dom-element-in-react-what-is-the-equilvalent-of-document-getele/38093981#38093981) – Shubham Khatri Dec 20 '18 at 05:07
  • 1
    Possible duplicate of [How to access a DOM element in React? What is the equilvalent of document.getElementById() in React](https://stackoverflow.com/questions/38093760/how-to-access-a-dom-element-in-react-what-is-the-equilvalent-of-document-getele) – Agney Dec 20 '18 at 05:07
  • did u people read the question or just wait to mark it ..... i mention i tried on stack overflow ans but that not give me any solution. plz read first then mark it as a duplicate. – sayalok Dec 20 '18 at 05:13
  • @sayalok Please define a ref on canvas to access it via a ref. Thats the reason its not working. – Shubham Khatri Dec 20 '18 at 06:00

3 Answers3

6

You can use Callback Refs to retrieve the ID:

class YourComponent extends React.Component {
  constructor(props) {
    super(props)
    this.canvas = null
  }

  componentDidMount() {
    console.log(this.canvas.id) // gives you "myCanvas"
  }


  render() {
    return (
      <React.Fragment>
        <div id="animSec">
          <canvas id="myCanvas" ref={c => {this.canvas = c}}></canvas>
        </div>
      </React.Fragment>
    )
  }
}

alternatively, for React v16.3+, you can use createRef():

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

  componentDidMount() {
    console.log(this.canvas.current.id) // gives you "myCanvas"
  }


  render() {
    return (
      <React.Fragment>
        <div id="animSec">
          <canvas id="myCanvas" ref={this.canvas}></canvas>
        </div>
      </React.Fragment>
    )
  }
Liren Yeo
  • 3,215
  • 2
  • 20
  • 41
  • thanks it did work. but can u explain a bit this line c => {this.canvas = c} why do i have to call the fun and pass the element through it ? – sayalok Dec 20 '18 at 06:06
  • 1
    https://reactjs.org/docs/refs-and-the-dom.html#callback-refs Firstly, understand that the lifecycle is like this: constructor -> render -> componentDidMount (cdm). Before mounting the component, constructor runs and declared `canvas` variable, then after the first render, we store in `this.canvas` using ref API, then we can access it in CDM. – Liren Yeo Dec 20 '18 at 06:11
  • After v16.3, there is a new createRef() method: https://reactjs.org/docs/refs-and-the-dom.html#creating-refs I will update the answer with this newer method. – Liren Yeo Dec 20 '18 at 06:13
  • thanks a lot . yeah that was the real reason . i didnt maintain lifecycle thing while i coding – sayalok Dec 20 '18 at 06:18
  • glad it worked out for you. do accept my answer if it helps, thanks ;) – Liren Yeo Dec 20 '18 at 06:21
1

If you set up a ref in your constructor as this.canvasRef = React.createRef() and apply it to your canvas as

<React.Fragment> 
  <div id="animSec">
    <canvas ref={this.canvasRef}></canvas>
  </div>
</React.Fragment>

You should be able to access the element directly. You can console log or check your dev tools to view the ref value. And (to my best knowledge), it's best practice to use Refs compared to querySelectors in React. You might also check out this post to see if you can work around with a method on canvas.

Ryan Brockhoff
  • 617
  • 1
  • 7
  • 8
0

You can try using document.getElementById('myCanvas') in a custom function or any life cycle method to target the desired element.
Note that this doesn't work if you're doing SSR with a framework like next.js because there is no document object in the server.

Muljayan
  • 3,588
  • 10
  • 30
  • 54
  • its send me undefined error Cannot read property 'width' of null – sayalok Dec 20 '18 at 05:10
  • Try using it in `componentDidMount` and to get the width use clientWidth. I tried it in the `componentDidMount` and console logged the output of `document.querySelector('#myCanvas')` – Muljayan Dec 20 '18 at 05:20
  • console.log(document.querySelector('#myCanvas')); inside componentDidMount no return inside constructor null – sayalok Dec 20 '18 at 05:30
  • That's odd. It worked for me. Try making a new component with only the ` ` and try to use the `document.querySelector('#myCanvas')` in componentDidMount – Muljayan Dec 20 '18 at 05:42
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/185535/discussion-between-sayalok-and-muljayan). – sayalok Dec 20 '18 at 05:52