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