Manipulate the DOM with React refs

Kent C. Dodds
InstructorKent C. Dodds
Share this video with your friends

Social Share Links

Send Tweet
Published 6 years ago
Updated 4 years ago

Often you'll find there's a jQuery plugin or JavaScript library which needs access to DOM nodes to work in your application. Other times you need access to the DOM node directly to get the value of form fields or for other reasons. In this lesson we'll learn how to do this using React's ref prop.

[00:00] We'll start by making a class called tilt that extends React.component. That'll have a render. We'll return a div, another div, yet another div, and this one is just going to spread this.props. On our root div, we'll have a classname, tiltRoot.

[00:24] Then we'll have a classname on this one called tiltChild. Then we'll go ahead and use that. We'll put tilt inside of here, put this inside of tilt, and then we'll add a div inside of here. That div will have a classname of totallyCentered.

[00:42] Next, we'll go ahead and add a ref prop. We'll say node is this.rootNode equals that node. Then in our componentDidMount, we can console.log(this.rootNode). Pop over developer tools, and we'll see we get that rootNode.

[01:01] Now, we can use this node with vanilla-tilt. Let's go ahead and bring in the vanilla-tilt library. I'll just paste a script here for that. Then we can use the vanilla-tilt library with the vanilla-tilt global. We'll say .init(this.rootNode).

[01:20] Then we can pass some options. We'll say max is 25, speed is 400, glare true, and max glare 05. We'll get rid of that console.log. Now, if we hover over it, we get that vanilla tilt.

[01:38] In review, to be able to manipulate the DOM directly, you need to pass a ref onto your element that you're rendering. When you pass a ref to an element like this, we're going to get a reference to the DOM node.

[01:51] If we were to pass a ref to tilt, then what we're going to get is a reference to the instance. It would be the same thing as this. We'll get this as a reference in our ref on a composite component, but because we're putting it on the div, we get access to the DOM node.

[02:10] We assign that to this.rootNode, and once the component's mounted, we have that node. We say, "Hey, vanilla-tilt, I want you to initialize on this node with these options." That gives us our really cool effect here.

Hozefa
Hozefa
~ 6 years ago

One thing might be worth explaining in the basic course is what is React.Component? Unless I missed the explanation, it's used in the examples but not explained why its used. As a beginner it could be confusing as to why React.Component is extended?

Kent C. Dodds
Kent C. Doddsinstructor
~ 6 years ago

That's a fantastic point Hozefa. I guess I just took that for granted and I should have a lesson explaining it. I may add it in the future because it could be really useful to know what the React.Component class even is and why extending it is necessary. Thanks for the idea!

If you want to play around with it, then head over to CodeSandbox.io and try creating an instance of React.Component and console log that :) Good luck!

Harsh Khandelwal
Harsh Khandelwal
~ 6 years ago

So from your suggestion to console log the React Component instance, I believe extending it gives me all the API to make my custom component work e.g like setState function?

Hozefa
Hozefa
~ 6 years ago

I was just generally asking what React.Component is all about. Doing a console log of that revels its a function(did not know that before)

codesandbox

function ReactComponent(props, context, updater) {
  this.props = props;
  this.context = context;
  this.refs = emptyObject;
  // We initialize the default updater but the real one gets injected by the
  // renderer.
  this.updater = updater || ReactNoopUpdateQueue_1;
}
Scott Spence
Scott Spence
~ 6 years ago

Is there a way to import tilt as a package?

So instead of adding the script to the html you can access it as a JS import?

Kent C. Dodds
Kent C. Doddsinstructor
~ 6 years ago

Hi Scott, Yes, you can install it from npm: https://www.npmjs.com/package/vanilla-tilt

Then:

import Tilt from 'vanilla-tilt'
Scott Spence
Scott Spence
~ 6 years ago

Thanks Kent, I was having a look at it in codesandbox.io and think I need to understand the differences between the class and the const element

I mean I know the const element is displaying the div's of the Tilt class but I'm struggling to understand why they're not all in one

Marcy Montross
Marcy Montross
~ 6 years ago

I'm following along using 'create-react-app' and I find this lesson confusing. I've imported vanilla-tilt as a package—both as 'react-tilt' and 'vanilla-tilt'. I keep getting an error: ''VanillaTilt' is not defined'. what am I doing wrong?

Kent C. Dodds
Kent C. Doddsinstructor
~ 6 years ago

HeyMarcy, Here's a working codesandbox. Hopefully this helps: https://codesandbox.io/s/14l00znlzq

Good luck!

Marcy Montross
Marcy Montross
~ 6 years ago

Thanks so much for your prompt reply. Turns out there was something else wrong. After a clean install of 'create-react-app', it worked fine.

I'm really enjoying the course. Thanks again!

Richard Fernandez
Richard Fernandez
~ 6 years ago

I'm trying to understand what the difference is between setting the root node and not setting it. I've played around with the code and taken out the ref={node => (this.rootNode = node)}, which (obviously) breaks the code.

I guess my question is, what does setting the rootNode do? And what element / rootNode does React reference if you do not set it?

Kent C. Dodds
Kent C. Doddsinstructor
~ 6 years ago

If you don't set this.rootNode then the value of this.rootNode will be undefined (which is why it breaks). The value it gets set to is the DOM node associated to what you're rendering if you pass it to a dom element (like <div>) but if you pass it to a composite (custom) class component (like <Tilt>), then the value it gets assigned to is the component instance.

Markdown supported.
Become a member to join the discussionEnroll Today