Search code examples
javascriptreactjsreact-nativeref

ref prop is not passed, TypeError: null is not an object (evaluating 'inputRef.current.focus')


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 ?


Solution

  • 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={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: "" })}
            />
    ...