joekevinrayan96
joekevinrayan96

Reputation: 634

Cannot read properties of undefined (reading 'focus') on calling focus on useRef current object

Here I have to call useRef and have the focus method to be called on Ref object. Below is the Input.tsx component.

import React, { useRef, useState } from "react";

const Input = (props: any) => {

const [text, setText] = useState<string>('');

const inputRef = useRef<any>();

const onChangeHandler = (e) => {
  setText(e.target.value)
};

const submitHandler = (event: React.FormEvent) => {
event.preventDefault();
if (!text) {
    inputRef.current.focus();
  }

};  

return (
    <div>
<form onSubmit={submitHandler}>
  <label htmlFor="label">label</label>
  <input
    ref={inputRef}
    value={text}
    type="text"
    id="email"
    onChange={onChangeHandler}
    />
<button type="submit">Submit</button>
</form>
</div>


);

};

export default Input;

If I don't define the useRef type to be 'any' I'm getting compile error. Where as defining it 'any' I'm getting runtime error of cannot read properties of undefined (reading 'focus'). I think I'm not initializing any value on useRef that's why I'm getting this error. But I also know I can't assign string, number or boolean value and call focus() there. How can I fix this issue. I'm using typescript by the way.

Upvotes: 0

Views: 6488

Answers (1)

joekevinrayan96
joekevinrayan96

Reputation: 634

I found the answer to my own question. The type of useRef.current for a text input field usually would be <HTMLInputElement | null> it cannot be undefined. Therefore this is how the code should be.

import React, { useRef, useState } from "react";

const Input = (props: any) => {
  const [text, setText] = useState<string>("");

  const inputRef = useRef<HTMLInputElement>(null); //made a change here

  const onChangeHandler = (e) => {
    setText(e.target.value);
  };

  const submitHandler = (event: React.FormEvent) => {
    event.preventDefault();
    if (!text) {
      inputRef.current!.focus(); //made a change here
    }
  };

  return (
    <div>
      <form onSubmit={submitHandler}>
        <label htmlFor="label">label</label>
        <input
          ref={inputRef}
          value={text}
          type="text"
          id="email"
          onChange={onChangeHandler}
        />
        <button type="submit">Submit</button>
      </form>
    </div>
  );
};

export default Input;

Thanks to one of the comments below my question.

Upvotes: 3

Related Questions