简体   繁体   中英

How to set focus on custom input in ReactJS using useRef and react hooks?

I am using custom input element and want to set focus on it after initial render. Here is my custom input element: (simple though)

import React from 'react';
import './Input.scss';

const input = (props) => (
    <input 
        type={props.inputtype} 
        className="input" 
        placeholder={props.hint}
        style={{width: props.width}} {...props}/>
);

export default input;

And this is how I am using it in my functional component:

const SignupPopup = (props) => {

const inputEmailRef = useRef(null);
//...
useEffect(() => {
    inputEmailRef.current.focus();
}, []);

return ( 
   <Input
      inputtype="email"
      hint="Email"
      width="100%"
      id="inputemail"
      ref={inputEmailRef}
      value={email}
      required
      onBlur={emailBlurHandler}
      onChange={inputChangeHandler}
      />);
}

Error:

TypeError: Cannot read property 'focus' of null

在此处输入图片说明

All examples and codes that I have seen work only on native <input ref={myRef} /> element but is there any way to do it in custom input element or wrapped input element?

You should use React.forwardRef to pass a ref to native input in your custom component:

import React from 'react';
import './Input.scss';

const input = React.forwardRef((props, ref) => (
    <input 
        type={props.inputtype} 
        className="input" 
        placeholder={props.hint}
        style={{width: props.width}}
        ref={ref}
        {...props}
    />
));

export default input;

More details:- https://en.reactjs.org/docs/forwarding-refs.html

You have to pass the ref using React.forwardRef .

In this way, you could access the ref of any React component in the parent.

const Input = React.forwardRef((props, ref) => (
     <input 
        ref={ref}
        type={props.inputtype} 
        className="input" 
        placeholder={props.hint}
        style={{width: props.width}} 
        {...props}
     />
));

I hope you already solved this. I will post my solution to future fellows with the same problem. There is a functional code snippet attached to the answer if you want to check how it works.

In React (tested on v17.0.2) you can use useRef hook to reference an specific element. In this case you will need to

  1. Import useRef . This can be done just like this:
import { useRef } from "react";
  1. Inside of your component (before return ), you have to add a const that will call the useRef method we just imported:
const inputRef = useRef();
  1. Then, you have to reference inputRef to an element:
<input
    ref={inputRef}
    placeholder="Enter a value"
/>
  1. Finally, you can do whatever you need with that element just like accesing it like this inputRef.current :
inputRef.current.select(); // or inputRef.current.focus(); in your case

 'use strict'; const e = React.createElement; const App = () => { const inputRef = React.useRef(); const handleSubmit = (e) => { e.preventDefault(); inputRef.current.select(); // you could also use inputRef.current.focus() if you only want to focus the input }; return( <form onSubmit={handleSubmit}> <h2> useRef select input example </h2> <input placeholder="Other input that I dont want to focus" /> <input ref={inputRef} placeholder="Enter a value" /> <button type="submit" > Submit </button> </form> ); } const domContainer = document.querySelector('#root');ReactDOM.render(e(App), domContainer);
 body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif; padding: 10px 70px; text-align: center; color: #DDD; background-color: #222; } form { padding: 0 20%; display: flex; flex-direction: column; } form * { margin-bottom: 0.5rem; }
 <script src="https://unpkg.com/react@17/umd/react.development.js"></script> <script src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script> <!-- Don't use this in production: --> <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script> <div id="root"></div>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM