Search code examples
reactjsfocusref

How to use "ref" to refer an element in React Stateless Component


I was trying to implement focus for the Submit button with Ref. I wanted to omit refering elements by ID.

import React, { useRef } from 'react'
import PropTypes from 'prop-types'

export const LabelComponent = () => {

  const createButton = enableCreateButton()
    ? <button ref={(input) => { this.createLabelBtn = input }} >Submit</button>
    : <button disabled ref={(input) => { this.createLabelBtn = input }} >Submit</button>

  const createLabelBtn = useRef();

  const focusCreateBtn = (e) => {
    if ((e.key === 'Enter') && (newLabel.name !== '')) {
      this.createLabelBtn.focus();
    }
  };

  return (
    <div className='create-label-container'>
      <input type='text'
        onKeyDown={(e) => { focusCreateBtn(e) }}
      />

      {createButton}
    </div>
  )
}

It gives following error.

Uncaught TypeError: Cannot set property 'createLabelBtn' of undefined

Uncaught TypeError: Cannot set property 'createLabelBtn' of undefined

What could be the issue here.?


Solution

  • Functional components are instanceless, therefore, no this to bind anything to or call upon. Set the ref prop on the button as so ref={createLabelBtn}, and to set the focus you need to access createLabelBtn.current to get at the current value of the ref.

    export const LabelComponent = ({ enableCreateButton }) => {
      const createLabelBtn = useRef(null);
    
      const focusCreateBtn = e => {
        if (e.key === "Enter") {
          createLabelBtn.current.focus();
        }
      };
    
      return (
        <div className="create-label-container">
          <input type="text" onKeyDown={focusCreateBtn} />
          <button
            // upon being focused upon, console log proof
            onFocus={() => console.log("Submit Focused!")}
            disabled={!enableCreateButton}
            ref={createLabelBtn}
          >
            Submit
          </button>
        </div>
      );
    };
    

    Edit strange-wood-chou6