Refs in React provide a way to access the underlying DOM element or React component instance directly.
Exposing DOM refs to parent components can break component encapsulation, but alternatives like ref forwarding or passing a ref as a differently named prop can be used. This is often referred to as “react get reference to element”. The ref attribute is a special attribute that can be attached to any component, allowing developers to reference the corresponding DOM node or React component instance.
This is particularly useful when you need to manage focus, trigger media playback, or integrate with third-party DOM libraries.
1class MyComponent extends React.Component { 2 constructor(props) { 3 super(props); 4 this.myRef = React.createRef(); 5 } 6 7 render() { 8 return <div ref={this.myRef} />; 9 } 10}
While React generally encourages the use of a declarative approach to manipulate the DOM, there are times when imperative manipulation is necessary. Refs provide an escape hatch from the React model to the raw DOM API. With refs, you can directly access DOM nodes and perform actions that aren't feasible with the standard React data flow.
1function handleClick() { 2 // Assume `myRef` is assigned to an input element 3 this.myRef.current.focus(); 4}
The ref attribute can be used to get a reference to a DOM element within a React component. This attribute accepts a callback function that receives the underlying DOM element as its argument. Alternatively, it can be assigned a ref object created by React.createRef().
1class CustomTextInput extends React.Component { 2 constructor(props) { 3 super(props); 4 this.textInput = React.createRef(); 5 } 6 7 focusTextInput = () => { 8 this.textInput.current.focus(); 9 }; 10 11 render() { 12 return ( 13 <input 14 type="text" 15 ref={this.textInput} 16 /> 17 ); 18 } 19}
The createRef method is used to create refs in class components. This method initializes a ref object, and the current property of this object is set to the corresponding DOM node when the component mounts.
1class MyComponent extends React.Component { 2 myRef = React.createRef(); 3 4 componentDidMount() { 5 const node = this.myRef.current; 6 // You can now access the DOM node directly 7 } 8 9 render() { 10 return <div ref={this.myRef} />; 11 } 12}
Callback refs provide more control over when refs are set and unset. Instead of passing a ref object to the ref attribute, you pass a function that will be called with the DOM element or class component instance when the component mounts, and with null when it unmounts.
1class MyComponent extends React.Component { 2 setMyRef = (element) => { 3 this.myRef = element; 4 }; 5 6 render() { 7 return <div ref={this.setMyRef} />; 8 } 9}
In class components, refs are commonly assigned to instance properties to provide a way to access them throughout the component. This is useful for accessing methods of a child component or triggering imperative animations. Refs can also be used in a parent component to access methods of a child component, although it is important to avoid breaking component encapsulation.
1class ParentComponent extends React.Component { 2 childRef = React.createRef(); 3 4 handleButtonClick = () => { 5 // You can call a method on the child component 6 this.childRef.current.someMethod(); 7 }; 8 9 render() { 10 return <ChildComponent ref={this.childRef} />; 11 } 12}
Function components do not have instances, so you cannot use refs to access component instances directly. However, if you need to access a DOM element within a function component, you can use the useRef hook.
1function MyFunctionalComponent() { 2 const myRef = React.useRef(null); 3 4 React.useEffect(() => { 5 const node = myRef.current; 6 // Perform actions on the DOM node 7 }, []); 8 9 return <div ref={myRef} />; 10}
Ref forwarding is a technique for automatically passing a ref through a component to one of its children. This is particularly useful for reusable component libraries and managing focus within a component hierarchy.
1const FancyButton = React.forwardRef((props, ref) => ( 2 <button ref={ref} className="FancyButton"> 3 {props.children} 4 </button> 5));
Managing focus is crucial for accessibility and user experience. Refs make managing focus straightforward, especially in complex components like modal dialogs where focus needs to be trapped within the dialog component for the duration of its visibility.
1class DialogComponent extends React.Component { 2 constructor(props) { 3 super(props); 4 this.firstTextInputRef = React.createRef(); 5 } 6 7 componentDidMount() { 8 this.firstTextInputRef.current.focus(); 9 } 10 11 render() { 12 return ( 13 <div className="dialog"> 14 <input 15 type="text" 16 ref={this.firstTextInputRef} 17 /> 18 {/* Other dialog inputs and elements */} 19 </div> 20 ); 21 } 22}
Refs can be used to control media elements like <audio>
or <video>
for media playback. This allows you to programmatically play, pause, or seek media, which is essential for creating custom media controls.
1class MediaPlayer extends React.Component { 2 videoRef = React.createRef(); 3 4 playVideo = () => { 5 this.videoRef.current.play(); 6 }; 7 8 pauseVideo = () => { 9 this.videoRef.current.pause(); 10 }; 11 12 render() { 13 return ( 14 <div> 15 <video ref={this.videoRef} src="path_to_video" /> 16 <button onClick={this.playVideo}>Play</button> 17 <button onClick={this.pauseVideo}>Pause</button> 18 </div> 19 ); 20 } 21}
Refs are particularly useful for reading values from text inputs in scenarios where you want to avoid using state for performance reasons or when you need to access the input value without triggering a re-render.
1class UncontrolledForm extends React.Component { 2 inputRef = React.createRef(); 3 4 handleSubmit = (event) => { 5 alert('A name was submitted: ' + this.inputRef.current.value); 6 event.preventDefault(); 7 }; 8 9 render() { 10 return ( 11 <form onSubmit={this.handleSubmit}> 12 <label> 13 Name: 14 <input type="text" ref={this.inputRef} /> 15 </label> 16 <button type="submit">Submit</button> 17 </form> 18 ); 19 } 20}
Sometimes, you might need to integrate React with third-party DOM libraries. Refs provide a way to give these libraries access to the underlying DOM element they need to operate.
1class DatePicker extends React.Component { 2 dateInputRef = React.createRef(); 3 4 componentDidMount() { 5 // Assume `initializeDatePicker` is a third-party library function 6 initializeDatePicker(this.dateInputRef.current); 7 } 8 9 render() { 10 return <input ref={this.dateInputRef} />; 11 } 12}
Imperative animations can be triggered using refs by accessing the DOM nodes and manipulating their styles or classes directly, which might be necessary when dealing with complex animations that are difficult to handle declaratively.
1class AnimatedComponent extends React.Component { 2 boxRef = React.createRef(); 3 4 animateBox = () => { 5 // Directly manipulate the DOM node for animation 6 this.boxRef.current.classList.add('start-animation'); 7 }; 8 9 render() { 10 return ( 11 <div ref={this.boxRef} className="box"> 12 {/* Content */} 13 </div> 14 ); 15 } 16}
Refs can be used to measure DOM elements to create responsive designs that adapt to the size of content dynamically, such as calculating the height of an element to adjust the surrounding layout.
1class ResponsiveComponent extends React.Component { 2 containerRef = React.createRef(); 3 4 componentDidMount() { 5 const height = this.containerRef.current.offsetHeight; 6 // Use `height` to adjust layout or perform other actions 7 } 8 9 render() { 10 return <div ref={this.containerRef}>Content</div>; 11 } 12}
While refs are powerful, they should be used sparingly as they can make your code less predictable and harder to maintain. Overuse of refs can lead to an imperative code style that goes against the declarative nature of React.
Understanding when to use refs versus state is crucial. State should be used for data that changes over time and causes a re-render, while refs are more suited for accessing DOM nodes or React elements that do not require re-renders.
Common mistakes with refs include overusing them for tasks that can be achieved with state, not considering the component lifecycle when accessing refs, and misunderstanding how refs work with function components. It's important to remember that refs do not trigger re-renders and should be used for actions that don't require a render update, such as managing focus or integrating with imperative animations.
1function TextInputWithFocusButton() { 2 const inputEl = useRef(null); 3 const onButtonClick = () => { 4 // `current` points to the mounted text input element 5 inputEl.current.focus(); 6 }; 7 return ( 8 <> 9 <input ref={inputEl} type="text" /> 10 <button onClick={onButtonClick}>Focus the input</button> 11 </> 12 ); 13}
Refs bypass the normal React data flow, so they should be used sparingly and only when necessary. Overuse of refs can lead to spaghetti code, where the data flow is hard to track and debug. It's often better to use state and props to handle changes in your application, reserving refs for cases where you need to directly interact with a DOM node or execute a React component's imperative methods.
When deciding between refs and state, consider whether the data you're working with is part of the render output or if it's something that doesn't need to be visualized. If it's the former, use state; if it's the latter, refs might be appropriate. For example, if you need to store the current value of an input element but don't need to render anything based on that value, a ref might be the right choice.
1class UncontrolledComponent extends React.Component { 2 constructor(props) { 3 super(props); 4 this.nameInput = React.createRef(); 5 } 6 7 render() { 8 return ( 9 <input 10 defaultValue="Bob" 11 type="text" 12 ref={this.nameInput} 13 /> 14 ); 15 } 16}
React refs are used for accessing DOM nodes or React elements that are rendered in the component. They are helpful for managing focus, reading values from the DOM, and integrating with imperative APIs. Refs provide a way to access the actual DOM node for tasks like measuring the size of an element or focusing an input field.
Using the ref attribute instead of the id attribute in React is recommended because it ensures that the references to DOM nodes are kept in sync with the component lifecycle. It also avoids potential conflicts with multiple elements having the same id in a single-page application and provides a more React-centric way of accessing DOM nodes.
Refs should not be overused because they can make the application less predictable and harder to maintain. They break the usual top-down data flow and can lead to code that is more difficult to understand. Instead, it's often better to use state and props for managing changes and data within the application.
Use refs for cases where you need to directly interact with a DOM node and when the interaction doesn't involve re-rendering the component. Use state when you need to keep track of data that changes over time and when those changes should result in a re-render to update the UI.
In this article, we've explored how to "react get reference to element" using the ref attribute, the importance of refs for managing focus, media playback, and text input, and how to integrate with third-party DOM libraries. We've also discussed the advanced use cases for refs, such as triggering imperative animations and performing DOM measurements for responsive design.
As we conclude, remember that while refs are a powerful tool in React, they should be used judiciously and with an understanding of their implications. Always consider the React data flow and component lifecycle when working with refs. Keep learning and exploring best practices to write more maintainable and predictable React applications.
Tired of manually designing screens, coding on weekends, and technical debt? Let DhiWise handle it for you!
You can build an e-commerce store, healthcare app, portfolio, blogging website, social media or admin panel right away. Use our library of 40+ pre-built free templates to create your first application using DhiWise.