Home > Software design >  ref prop is not passed, TypeError: null is not an object (evaluating 'inputRef.current.focus�
ref prop is not passed, TypeError: null is not an object (evaluating 'inputRef.current.focus�

Time:03-19

I am making a custom input component


const CustomInput = (props) => {
  console.log(props);
  return (
    <TextInput
      {...props}
      ref={props.ref}
      placeholder={props.placeholder}
      style={{ ...styles.text, ...props.style }}
    />
  );
};

in the file I want to use it I have

const ForgottenPasswordScreen = (props) => {
...
const inputRef = React.createRef();

  useEffect(() => {
    inputRef.current.focus();
  }, []);
...

<CustomInput
          placeholder={"E-mail..."}
          value={email.value}
          ref={inputRef}
          onChangeText={(text) => setEmail({ value: text, error: "" })}
        />
...

If I am using normal TextInput there is no problem, but when I try to use my CustomInput, i get the error

TypeError: null is not an object (evaluating 'inputRef.current.focus')

I don't get why ref={props.ref} is not doing the job. I thought that ref will be passed to my component too. How to pass ref properly ?

CodePudding user response:

The ref is not inside of props. When using ref as a prop, the FunctionComponents should be created with forwardRef() which takes a function that has two arguments, props and ref.

Here's the example from the documentation https://reactjs.org/docs/forwarding-refs.html

const FancyButton = React.forwardRef((props, ref) => (
  <button ref={ref} className="FancyButton">
    {props.children}
  </button>
));

// You can now get a ref directly to the DOM button:
const ref = React.createRef();
<FancyButton ref={ref}>Click me!</FancyButton>;

CodePudding user response:

So with this we can determine if we want it to select the input or not

the reason is that the ref cannot be passed down as it is a ref to that component unless you use React.forwardRef but this is a way without forwardRef

import { useEffect, useRef } from "react"; import "./styles.css";

const InsantSelectInput = (props) => {
  const inputRef = useRef(null)

  useEffect(() => {
    if(inputRef && inputRef.current)
    inputRef.current.focus()
  }, [inputRef])
  return <input {...props} ref={inputRef} placeholder={props.placeholder} />;
}

const CustomInput = (props) => {
  return <>
  {props.isSelectedInput && <InsantSelectInput {...props} />}
  {!props.isSelectedInput && <input {...props}  placeholder={props.placeholder} />}
  </>
};

export default function App() {
  return (
    <div className="App">
      <h1>Hello CodeSandbox</h1>
      <h2>Start editing to see some magic happen!</h2>
      <CustomInput
        placeholder={"E-mail..."}
        value={""}
        isSelectedInput
        onChangeText={(text) => console.log({ value: text, error: "" })}
      />
    </div>
  );
}

OR with forwardRef

const CustomInput = React.forwardRef((props, ref) => {
      return <>
      <TextInput
      {...props}
      ref={props.ref}
      placeholder={props.placeholder}
      style={{ ...styles.text, ...props.style }}
    />
    });

const ForgottenPasswordScreen = (props) => {
...
const inputRef = React.createRef();

  useEffect(() => {
    inputRef.current.focus();
  }, []);
...

<CustomInput
          placeholder={"E-mail..."}
          value={email.value}
          ref={inputRef}
          onChangeText={(text) => setEmail({ value: text, error: "" })}
        />
...
  • Related