{"componentChunkName":"component---src-templates-tag-js","path":"/tags/refs/","result":{"data":{"site":{"siteMetadata":{"title":"LoginRadius Blog"}},"allMarkdownRemark":{"totalCount":1,"edges":[{"node":{"fields":{"slug":"/engineering/react-with-refs/"},"html":"<p>In this article, We will discuss the manipulation of DOM elements with Ref directly with React. </p>\n<p>React Framework builds your components and abstracts your code away from manipulation within the DOM but still leaves the door open for developers to access it. Reason are few cases where it might be necessary. That's why React provides an escape hatch know as <code>refs</code>.</p>\n<p>Refs are a function that use to access the DOM from components. You only need to attach a <code>ref</code> to the element in your application to provide access to it from anywhere within your component without making use of props and all. </p>\n<p>We can also use Refs to direct access to React elements and use callbacks with them.</p>\n<p>We should only use <code>refs</code> when the required interaction cannot be achieved using state and props.</p>\n<h2 id=\"use-refs\" style=\"position:relative;\"><a href=\"#use-refs\" aria-label=\"use refs permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Use Refs</h2>\n<p>We can use <code>refs</code> to do anything that needs to be manipulated in the DOM. Some good cases like focus, test selection, media playback, triggering mandatory animations, or integration with the third-party DOM library.</p>\n<p>Note: We should avoid using refs because it removes the purpose of using React.   For example, If you want to show and hide a \t<code>popup</code> component. We should use a boolean prop for it instead of manipulating dom.\n</p>\n<h3 id=\"creating-refs\" style=\"position:relative;\"><a href=\"#creating-refs\" aria-label=\"creating refs permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Creating Refs</h3>\n<p>We can use <code>React.createRef()</code>method to create Refs, and then we can attach to a Dom element via the <code>ref</code> attribute after that, we can access and modify that element through the ref. </p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"javascript\" data-index=\"0\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk4\">class</span><span class=\"mtk1\"> </span><span class=\"mtk10\">App</span><span class=\"mtk1\"> </span><span class=\"mtk4\">extends</span><span class=\"mtk1\"> </span><span class=\"mtk10\">React</span><span class=\"mtk1\">.</span><span class=\"mtk10\">Component</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk4\">constructor</span><span class=\"mtk1\">(</span><span class=\"mtk12\">props</span><span class=\"mtk1\">) {  </span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">super</span><span class=\"mtk1\">(</span><span class=\"mtk12\">props</span><span class=\"mtk1\">);  </span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">this</span><span class=\"mtk1\">.</span><span class=\"mtk12\">myRef</span><span class=\"mtk1\"> = </span><span class=\"mtk12\">React</span><span class=\"mtk1\">.</span><span class=\"mtk11\">createRef</span><span class=\"mtk1\">();</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk11\">render</span><span class=\"mtk1\">() {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">div</span><span class=\"mtk1\"> </span><span class=\"mtk12\">ref</span><span class=\"mtk1\">=</span><span class=\"mtk4\">{this</span><span class=\"mtk1\">.</span><span class=\"mtk12\">myRef</span><span class=\"mtk4\">}</span><span class=\"mtk1\"> </span><span class=\"mtk17\">/&gt;</span><span class=\"mtk1\">; </span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span></code></pre>\n<p>In above code, We created <code>this.myRef</code> in the constructor by calling <code>React.createRef()</code>  method.</p>\n<p>Then in the <code>render</code> method , we attached the returned value to ref of the div element,  a reference to the node becomes accessible at the <code>current</code> attribute of the ref.</p>\n<p>We should not use <code>ref</code> attribute on function components because they do not have instances.</p>\n<p>React will assign the <code>current</code> property with Dom element when component mount and assign null to it when component unmount.  </p>\n<p><code>ref</code> updates happen before <code>componentDidMount</code> or <code>componentDidUpdate</code> methods.</p>\n<p>We can pass refs as props to the component. Example:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"javascript\" data-index=\"1\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk4\">function</span><span class=\"mtk1\"> </span><span class=\"mtk11\">MyCustomTextInput</span><span class=\"mtk1\"> ({ </span><span class=\"mtk12\">myInputRef</span><span class=\"mtk1\"> }) {  </span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">input</span><span class=\"mtk1\"> </span><span class=\"mtk12\">ref</span><span class=\"mtk1\">=</span><span class=\"mtk4\">{</span><span class=\"mtk12\">myInputRef</span><span class=\"mtk4\">}</span><span class=\"mtk1\"> </span><span class=\"mtk17\">/&gt;</span><span class=\"mtk1\">;  </span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">class</span><span class=\"mtk1\"> </span><span class=\"mtk10\">App</span><span class=\"mtk1\"> </span><span class=\"mtk4\">extends</span><span class=\"mtk1\"> </span><span class=\"mtk10\">React</span><span class=\"mtk1\">.</span><span class=\"mtk10\">Component</span><span class=\"mtk1\"> {  </span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk4\">constructor</span><span class=\"mtk1\">(</span><span class=\"mtk12\">props</span><span class=\"mtk1\">) {  </span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">super</span><span class=\"mtk1\">(</span><span class=\"mtk12\">props</span><span class=\"mtk1\">);  </span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">this</span><span class=\"mtk1\">.</span><span class=\"mtk12\">myInputRef</span><span class=\"mtk1\"> = </span><span class=\"mtk12\">React</span><span class=\"mtk1\">.</span><span class=\"mtk11\">createRef</span><span class=\"mtk1\">();  </span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  } </span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk11\">componentDidMount</span><span class=\"mtk1\">() {  </span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">this</span><span class=\"mtk1\">.</span><span class=\"mtk12\">myInputRef</span><span class=\"mtk1\">.</span><span class=\"mtk12\">current</span><span class=\"mtk1\">.</span><span class=\"mtk11\">focus</span><span class=\"mtk1\">();  </span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk11\">render</span><span class=\"mtk1\">() {  </span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> </span><span class=\"mtk17\">&lt;</span><span class=\"mtk10\">MyCustomTextInput</span><span class=\"mtk1\"> </span><span class=\"mtk12\">inputRef</span><span class=\"mtk1\">=</span><span class=\"mtk4\">{this</span><span class=\"mtk1\">.</span><span class=\"mtk12\">myInputRef</span><span class=\"mtk4\">}</span><span class=\"mtk1\"> </span><span class=\"mtk17\">/&gt;</span><span class=\"mtk1\">;  </span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span></code></pre>\n<p>In above code, <code>App</code> passed its ref as props to <code>MyCustomTextInput</code> component.</p>\n<h3 id=\"callback-refs\" style=\"position:relative;\"><a href=\"#callback-refs\" aria-label=\"callback refs permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Callback Refs</h3>\n<p>We can create ref using another way called <code>callback refs</code>; it gives us more fine-grain control over when refs are set and unset within the component.</p>\n<p>Instead of passing <code>ref</code> returned by <code>createRef()</code> method, we will pass a function to <code>ref</code> attribute.\nThe function receives React component instance or DOM element, which can be stored and accessed anywhere.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"javascript\" data-index=\"2\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk4\">class</span><span class=\"mtk1\"> </span><span class=\"mtk10\">App</span><span class=\"mtk1\"> </span><span class=\"mtk4\">extends</span><span class=\"mtk1\"> </span><span class=\"mtk10\">React</span><span class=\"mtk1\">.</span><span class=\"mtk10\">Component</span><span class=\"mtk1\"> {  </span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk11\">componentDidMount</span><span class=\"mtk1\">() {  </span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">this</span><span class=\"mtk1\">.</span><span class=\"mtk12\">input</span><span class=\"mtk1\">.</span><span class=\"mtk11\">focus</span><span class=\"mtk1\">();  </span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  } </span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk11\">render</span><span class=\"mtk1\">() {  </span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> (    </span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">input</span><span class=\"mtk1\"> </span><span class=\"mtk12\">ref</span><span class=\"mtk1\">=</span><span class=\"mtk4\">{</span><span class=\"mtk12\">element</span><span class=\"mtk1\"> </span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\"> (</span><span class=\"mtk4\">this</span><span class=\"mtk1\">.</span><span class=\"mtk12\">input</span><span class=\"mtk1\"> = </span><span class=\"mtk12\">element</span><span class=\"mtk1\">)</span><span class=\"mtk4\">}</span><span class=\"mtk1\"> </span><span class=\"mtk17\">/&gt;</span><span class=\"mtk1\">;   </span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    );  </span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  }  </span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span></code></pre>\n<p>In the above code, React will call the ref callback t store the reference of the input element when the component mounts; then, it will focus the input element automatically and when the component unmounts, call it with null.</p>\n<p>We can pass callback refs between components . Example:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"javascript\" data-index=\"3\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk4\">function</span><span class=\"mtk1\"> </span><span class=\"mtk11\">MyCustomTextInput</span><span class=\"mtk1\">({ </span><span class=\"mtk12\">inputRef</span><span class=\"mtk1\"> }) {  </span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">input</span><span class=\"mtk1\"> </span><span class=\"mtk12\">ref</span><span class=\"mtk1\">=</span><span class=\"mtk4\">{</span><span class=\"mtk12\">inputRef</span><span class=\"mtk4\">}</span><span class=\"mtk1\"> </span><span class=\"mtk17\">/&gt;</span><span class=\"mtk1\">;  </span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">class</span><span class=\"mtk1\"> </span><span class=\"mtk10\">App</span><span class=\"mtk1\"> </span><span class=\"mtk4\">extends</span><span class=\"mtk1\"> </span><span class=\"mtk10\">React</span><span class=\"mtk1\">.</span><span class=\"mtk10\">Component</span><span class=\"mtk1\"> {  </span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk11\">componentDidMount</span><span class=\"mtk1\">() {  </span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">this</span><span class=\"mtk1\">.</span><span class=\"mtk12\">myInputElement</span><span class=\"mtk1\">.</span><span class=\"mtk11\">focus</span><span class=\"mtk1\">();  </span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  } </span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk11\">render</span><span class=\"mtk1\">() {  </span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> </span><span class=\"mtk17\">&lt;</span><span class=\"mtk10\">MyCustomTextInput</span><span class=\"mtk1\"> </span><span class=\"mtk12\">inputRef</span><span class=\"mtk1\">=</span><span class=\"mtk4\">{</span><span class=\"mtk12\">el</span><span class=\"mtk1\"> </span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\"> (</span><span class=\"mtk4\">this</span><span class=\"mtk1\">.</span><span class=\"mtk12\">myInputElement</span><span class=\"mtk1\"> = </span><span class=\"mtk12\">el</span><span class=\"mtk1\">)</span><span class=\"mtk4\">}</span><span class=\"mtk1\"> </span><span class=\"mtk17\">/&gt;</span><span class=\"mtk1\">;  </span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  } </span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span></code></pre>\n<p>In the above code, We passed the function to <code>inputRef</code> and access it in <code>App</code> component so we can call <code>focus</code> on it to focus the input element.</p>\n<h3 id=\"caveats-with-callback-refs\" style=\"position:relative;\"><a href=\"#caveats-with-callback-refs\" aria-label=\"caveats with callback refs permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Caveats with callback refs</h3>\n<p>Callback refs are calling two times during updates if they are defined as an inline function. This is because a new instance of the function is created with each render. We can avoid this by calling it a method of a class.</p>\n<p>To understand more about React refs. Read <a href=\"https://reactjs.org/docs/refs-and-the-dom.html\">Refs and the DOM</a></p>\n<style class=\"grvsc-styles\">\n  .grvsc-container {\n    overflow: auto;\n    -webkit-overflow-scrolling: touch;\n    padding-top: 1rem;\n    padding-top: var(--grvsc-padding-top, var(--grvsc-padding-v, 1rem));\n    padding-bottom: 1rem;\n    padding-bottom: var(--grvsc-padding-bottom, var(--grvsc-padding-v, 1rem));\n    border-radius: 8px;\n    border-radius: var(--grvsc-border-radius, 8px);\n    font-feature-settings: normal;\n  }\n  \n  .grvsc-code {\n    display: inline-block;\n    min-width: 100%;\n  }\n  \n  .grvsc-line {\n    display: inline-block;\n    box-sizing: border-box;\n    width: 100%;\n    padding-left: 1.5rem;\n    padding-left: var(--grvsc-padding-left, var(--grvsc-padding-h, 1.5rem));\n    padding-right: 1.5rem;\n    padding-right: var(--grvsc-padding-right, var(--grvsc-padding-h, 1.5rem));\n  }\n  \n  .grvsc-line-highlighted {\n    background-color: var(--grvsc-line-highlighted-background-color, transparent);\n    box-shadow: inset var(--grvsc-line-highlighted-border-width, 4px) 0 0 0 var(--grvsc-line-highlighted-border-color, transparent);\n  }\n  \n  .dark-default-dark {\n    background-color: #1E1E1E;\n    color: #D4D4D4;\n  }\n  .dark-default-dark .mtk4 { color: #569CD6; }\n  .dark-default-dark .mtk1 { color: #D4D4D4; }\n  .dark-default-dark .mtk10 { color: #4EC9B0; }\n  .dark-default-dark .mtk12 { color: #9CDCFE; }\n  .dark-default-dark .mtk11 { color: #DCDCAA; }\n  .dark-default-dark .mtk15 { color: #C586C0; }\n  .dark-default-dark .mtk17 { color: #808080; }\n</style>","frontmatter":{"date":"April 16, 2021","updated_date":null,"title":"React with Ref","tags":["React","Refs","DOM"],"coverImage":{"childImageSharp":{"fluid":{"aspectRatio":1.5037593984962405,"src":"/static/0e4deace8ac6b8fceb2ca7ce559fc393/ee604/title-image.png","srcSet":"/static/0e4deace8ac6b8fceb2ca7ce559fc393/69585/title-image.png 200w,\n/static/0e4deace8ac6b8fceb2ca7ce559fc393/497c6/title-image.png 400w,\n/static/0e4deace8ac6b8fceb2ca7ce559fc393/ee604/title-image.png 800w,\n/static/0e4deace8ac6b8fceb2ca7ce559fc393/f3583/title-image.png 1200w","sizes":"(max-width: 800px) 100vw, 800px"}}},"author":{"id":"Versha Gupta","github":"vershagupta","avatar":null}}}}]}},"pageContext":{"tag":"Refs"}},"staticQueryHashes":["1171199041","1384082988","2100481360","23180105","528864852"]}