How to set focus on an input field after rendering?
Asked Answered
L

29

966

What's the react way of setting focus on a particular text field after the component is rendered?

Documentation seems to suggest using refs, e.g:

Set ref="nameInput" on my input field in the render function, and then call:

this.refs.nameInput.getInputDOMNode().focus(); 

But where should I call this? I've tried a few places but I cannot get it to work.

Lancey answered 5/3, 2015 at 23:28 Comment(1)
Don't bother reading all the answers if you are bound by the ESLint rule jsx-a11y/no-autofocus.Ceraceous
T
801

You should do it in componentDidMount and refs callback instead. Something like this

componentDidMount(){
   this.nameInput.focus(); 
}

class App extends React.Component{
  componentDidMount(){
    this.nameInput.focus();
  }
  render() {
    return(
      <div>
        <input 
          defaultValue="Won't focus" 
        />
        <input 
          ref={(input) => { this.nameInput = input; }} 
          defaultValue="will focus"
        />
      </div>
    );
  }
}
    
ReactDOM.render(<App />, document.getElementById('app'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.3.1/react.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.3.1/react-dom.js"></script>
<div id="app"></div>
Trimolecular answered 6/3, 2015 at 0:19 Comment(14)
This is the correct answer, but it did not work for me as my component first renders nothing, until another button is clicked. This meant that it was already mounted, so I had to add this.refs.nameInput.getDOMNode().focus(); in componentDidUpdate instead of componentDidMount.Lancey
Why, when element.focus() is called, does it put the cursor at the beginning of the input? I saw this (what I consider a) bug in my app, in chrome, actually in a <textarea> and now checking your demos here it's the same.Aviv
Warning: React.findDOMNode is deprecated. Please use ReactDOM.findDOMNode from require('react-dom') instead.Oxalate
How would you go about doing this if you have a stateless component?Aptitude
@HuwDavies I guess you'd do it using a ref Callback Attribute on the <input> element. Something like <input ref={ (component) => ReactDOM.findDOMNode(component).focus() } />Boothe
I get "Cannot set property 'nameInput' of undefined" when I try to do ref={(input) => { this.nameInput = input; }}Nitrometer
@Nitrometer have a debugger; inside the method and inspect what this refers toTrimolecular
For some reason immediate invocation of .focus() didn't work in my app, but with short (insignificant) timeout it did: componentDidMount() { setTimeout(() => { this.textInput.focus(); }, 10); }Charbonneau
@Charbonneau Ideally that shouldn't be required. I believe it depends on how your application/component works.Trimolecular
I found that in 16, having dev tools open puts the focus in the psuedo cli/terminal which stopped the focus from working in firefox. Closing it suddenly made it workign but onl after I had spent 3 hours on trying to under it....Phore
Why we not just use ref={(input) => { input.focus()}} ? This solution works fine for me.Nightwalker
Lazy I am to test this.. But answer from @FakeRainBrigand worked like charm <input type="text" autoFocus />Dunaway
this.nameInput.current.focus();Alrich
@Nightwalker that made it focus on every render for me instead of just first oneClaudclauddetta
S
1207

@Dhiraj's answer is correct, and for convenience you can use the autoFocus prop to have an input automatically focus when mounted:

<input autoFocus name=...

Note that in jsx it's autoFocus (capital F) unlike plain old html which is case-insensitive.

Selangor answered 6/3, 2015 at 2:1 Comment(17)
Note that in jsx its autoFocus (capital F) unlike plain old html which is case-insensitive.Syzran
Very Good, Got here after a long fruitless search :) FYI - I ended up using React.DOM.input({ type: 'text', defaultValue: content, autoFocus: true, onFocus: function(e) {e.target.select();} })Pyretotherapy
@RemiSture did you try it and see that it's not working?Selangor
@RemiSture That's an iOS feature. You unfortunately can't do anything about it.Putnam
I find that autoFocus only works on first page render. See codepen.io/ericandrewlewis/pen/PbgwqJ?editors=1111 the input should be focused after 3 seconds.Colner
@EricAndrewLewis the input isn't remounting in your code.Selangor
+1 for this method. It's worth mentioning that this doesn't just use HTML5 unreliable autofocus attribute, it actually uses focus() on DOM mount in react-dom so it's quite reliable.Waldner
As far as I can tell, @Aaron's comment is no longer valid. I only see reference to autoFocus mapping to the HTML5 autofocus attribute now. Perhaps this changed recently to be more consistent with HTML5?Algin
@DanaWoodman The implementation has dramatically changed but it appears it's still the same strategy: autoFocus just calls focus() on mount.Waldner
Not only "for convenience" but also if your component is a functional component.Illumination
It didn't do what I originally intended but it's a nice effect if you open the page (it puts the focus in the input field automatically)Dhu
This should be the accepted answer - unless you need the ref to do other things with the input, this is a much more natural web solution that doesn't need extra react code :)Poleaxe
+1 for the note on capital F. Was struggling to figure out why one component with autoFocus was working properly while another wasn't. After seeing this answer the lowercase f in the non-working component became obvious.Vincenz
By far the easiest way! Works on buttons tooGwin
It's worth mentioning that autoFocus is actually bad for accessibility and can have a negative impact on the user experience. dequeuniversity.com/rules/axe-linter/1.0/…Beaumarchais
In 2022 and inside a functional Component / Hooks, I am ignoring @Dhiraj's answer (not using refs callback), and simply using the attribute autoFocus, and it seems to work !? Hopefully it's the correct way to do it.Thill
It doesn't work at all in my React 18 application. What did work is regular: ``` const inputRef = useRef<HTMLInputElement>(null) useEffect(() => { if (inputRef.current != null) { inputRef.current.focus() } }, [inputRef]) ```Nona
T
801

You should do it in componentDidMount and refs callback instead. Something like this

componentDidMount(){
   this.nameInput.focus(); 
}

class App extends React.Component{
  componentDidMount(){
    this.nameInput.focus();
  }
  render() {
    return(
      <div>
        <input 
          defaultValue="Won't focus" 
        />
        <input 
          ref={(input) => { this.nameInput = input; }} 
          defaultValue="will focus"
        />
      </div>
    );
  }
}
    
ReactDOM.render(<App />, document.getElementById('app'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.3.1/react.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.3.1/react-dom.js"></script>
<div id="app"></div>
Trimolecular answered 6/3, 2015 at 0:19 Comment(14)
This is the correct answer, but it did not work for me as my component first renders nothing, until another button is clicked. This meant that it was already mounted, so I had to add this.refs.nameInput.getDOMNode().focus(); in componentDidUpdate instead of componentDidMount.Lancey
Why, when element.focus() is called, does it put the cursor at the beginning of the input? I saw this (what I consider a) bug in my app, in chrome, actually in a <textarea> and now checking your demos here it's the same.Aviv
Warning: React.findDOMNode is deprecated. Please use ReactDOM.findDOMNode from require('react-dom') instead.Oxalate
How would you go about doing this if you have a stateless component?Aptitude
@HuwDavies I guess you'd do it using a ref Callback Attribute on the <input> element. Something like <input ref={ (component) => ReactDOM.findDOMNode(component).focus() } />Boothe
I get "Cannot set property 'nameInput' of undefined" when I try to do ref={(input) => { this.nameInput = input; }}Nitrometer
@Nitrometer have a debugger; inside the method and inspect what this refers toTrimolecular
For some reason immediate invocation of .focus() didn't work in my app, but with short (insignificant) timeout it did: componentDidMount() { setTimeout(() => { this.textInput.focus(); }, 10); }Charbonneau
@Charbonneau Ideally that shouldn't be required. I believe it depends on how your application/component works.Trimolecular
I found that in 16, having dev tools open puts the focus in the psuedo cli/terminal which stopped the focus from working in firefox. Closing it suddenly made it workign but onl after I had spent 3 hours on trying to under it....Phore
Why we not just use ref={(input) => { input.focus()}} ? This solution works fine for me.Nightwalker
Lazy I am to test this.. But answer from @FakeRainBrigand worked like charm <input type="text" autoFocus />Dunaway
this.nameInput.current.focus();Alrich
@Nightwalker that made it focus on every render for me instead of just first oneClaudclauddetta
C
353

Focus on mount

If you just want to focus an element when it mounts (initially renders) a simple use of the autoFocus attribute will do.

<input type="text" autoFocus />

Dynamic focus

to control focus dynamically use a general function to hide implementation details from your components.

React 16.8 + Functional component - useFocus hook

const FocusDemo = () => {

    const [inputRef, setInputFocus] = useFocus()

    return (
        <> 
            <button onClick={setInputFocus} >
               Focus
            </button>
            <input ref={inputRef} />
        </>
    )
    
}

const useFocus = () => {
    const htmlElRef = useRef(null)
    const setFocus = () => {htmlElRef.current &&  htmlElRef.current.focus()}

    return [ htmlElRef, setFocus ] 
}

Full Demo

React 16.3 + Class Components - utilizeFocus

class App extends Component {
  constructor(props){
    super(props)
    this.inputFocus = utilizeFocus()
  }

  render(){
    return (
      <> 
          <button onClick={this.inputFocus.setFocus}>
             Focus
          </button>
          <input ref={this.inputFocus.ref}/>
      </>
    )
  } 
}
const utilizeFocus = () => {
    const ref = React.createRef()
    const setFocus = () => {ref.current &&  ref.current.focus()}

    return {setFocus, ref} 
}

Full Demo

Cuccuckold answered 12/1, 2019 at 12:27 Comment(14)
This answer contains the right approach for React Hooks. Super! It doesn't typecheck as-is in TypeScript but one (ugly) way to make it work: (1) (htmlElRef.current as any).focus() and (2) return {htmlElRef, setFocus} instead of array.Apostrophize
@AhmedFasih, I am aware of what you are saying, but I think it is out of scope for this thread. If you return an object it makes it more difficult to control the name of the variable, which could be a problem if you want to use useFocus for more than one element.Cuccuckold
Here is useFocus written in Typescript. gist.github.com/carpben/de968e377cbac0ffbdefe1ab56237573Cuccuckold
@BenCarp Small suggestion for hooks, might be better to put the set in the second position like const [inputRef, setInputFocus] = useFocus(). This matches useState more. First the object, then the setter of that objectIncisure
@Rubanov, thanks. I adjusted the code per your suggestion.Cuccuckold
I noticed the Stackblitz demo doesn't work perfectly on Firefox. There is no issue when running it locally. I believe it is a Stackblitz thing.Cuccuckold
@BenCarp Hi, I really like your way of making focus but when I try to use your examole in Class based component, I get: Can't perform a React state update on an unmounted component. error. Can you help to solve this?Deangelo
@Gido, I'd love to help. But I doubt if it is related to the class method I present, because there is no state update in that example. Can you please build a minimal demo to present this error in an online React editor (CodeSandBox or StackBlitz) and I can try to check it there.Cuccuckold
@BenCarp I am posting the link to my code: codesandbox.io/s/busy-hill-ydgx7?file=/src/App.js Here you can see that I am trying to use onKeyDown to change the focus but it doesn't change and shows the error. Codesandbox somehow doesn't show, however button doesn't change focusDeangelo
@Gido, see my comments codesandbox.io/s/keen-sun-3upm4?file=/src/App.js.Cuccuckold
I tried something similar but couldn't make it work with a custom input item. Could you take a look here? #64543329Crevice
@jnl, I see that you deleted the question. If it's still relevant let me know.Cuccuckold
This answer works great for html input, but I couldn't make it work for React material ui TextField component. Can you please help me?Dichroic
This answer works great for html input, I got stuck for a while using React material ui TextField component instead of the input element. You should use the inputRef attribute instead of the ref for the TextField component.Dichroic
C
233

As of React 0.15, the most concise method is:

<input ref={input => input && input.focus()}/>
Chatham answered 25/10, 2016 at 8:43 Comment(8)
This also handles the scenarios outside of the initial render whereas just using autoFocus does not.Actomyosin
question, when would input be false? I'm referring to the expression inside the arrow function.Martinic
@Martinic it's null until the component is mounted and/or after it has been unmounted (I don't remember for sure which is the case).Chatham
The only issue with this is that it focuses input on any re-render which might not be desired..Detour
Doesn't work in my case (using Ant Design input component)Janinajanine
YES!! Thank you so much! -- My case was focusing the text input in React Native, based on a prop that showed the modal or not. This worked for me! ref={input => input && this.props.showModal && input.focus()}Catherin
this works for me. but after pressing tab focus goes out of modal. Any suggestion ? @IlyaSemenovRoutinize
This looks wrong -- the React docs say "Calling ref.current.focus() during render is wrong because it is a side effect. Side effects should either be placed inside an event handler or be declared with useEffect." cf. react.dev/learn/…Voluminous
D
71

If you just want to make autofocus in React, it's simple.

<input autoFocus type="text" />

While if you just want to know where to put that code, answer is in componentDidMount().

v014.3

componentDidMount() {
    this.refs.linkInput.focus()
}

In most cases, you can attach a ref to the DOM node and avoid using findDOMNode at all.

Read the API documents here: https://facebook.github.io/react/docs/top-level-api.html#reactdom.finddomnode

Doscher answered 4/12, 2015 at 5:3 Comment(1)
And remember to capitalize that F! (Note to self and others, not to answerer).Cloutier
O
64

React 16.3 added a new convenient way to handle this by creating a ref in component's constructor and use it like below:

class MyForm extends Component {
  constructor(props) {
      super(props);

      this.textInput = React.createRef();
  }

  componentDidMount() {
    this.textInput.current?.focus();
  }

  render() {
    return(
      <div>
        <input ref={this.textInput} />
      </div>
    );
  }
}

For more details about React.createRef, you can check this article in React blog.

Update:

Starting from React 16.8, useRef hook can be used in function components to achieve the same result:

import React, { useEffect, useRef } from 'react';

const MyForm = () => {
  const textInput = useRef(null);

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

  return (
    <div>
      <input ref={textInput} />
    </div>
  );
};
Oust answered 16/1, 2019 at 20:50 Comment(2)
A small change: textInput.current?.focus();Pleading
if you're using typescript, make sure to type the ref: useRef<HTMLInputElement>(null)Eisenhower
T
30

The React docs now have a section for this. https://facebook.github.io/react/docs/more-about-refs.html#the-ref-callback-attribute

 render: function() {
  return (
    <TextInput
      ref={function(input) {
        if (input != null) {
          input.focus();
        }
      }} />
    );
  },
Thorazine answered 28/4, 2016 at 21:42 Comment(2)
I think this is a good way of doing it for this particular scenario.Coact
I didn't need to autofocus on mount, was just looking for the element to remain focused when entering a value. This worked perfectly for that scenario. (using react 15)Borosilicate
K
28

I just ran into this issue and I'm using react 15.0.1 15.0.2 and I'm using ES6 syntax and didn't quite get what I needed from the other answers since v.15 dropped weeks ago and some of the this.refs properties were deprecated and removed.

In general, what I needed was:

  1. Focus the first input (field) element when the component mounts
  2. Focus the first input (field) element with an error (after submit)

I'm using:

  • React Container/Presentation Component
  • Redux
  • React-Router

Focus the First Input Element

I used autoFocus={true} on the first <input /> on the page so that when the component mounts, it will get focus.

Focus the First Input Element with an Error

This took longer and was more convoluted. I'm keeping out code that isn't relevant to the solution for brevity.

Redux Store / State

I need a global state to know if I should set the focus and to disable it when it was set, so I don't keep re-setting focus when the components re-render (I'll be using componentDidUpdate() to check for setting focus.)

This could be designed as you see fit for you application.

{
    form: {
        resetFocus: false,
    }
}

Container Component

The component will need to have the resetfocus property set and a callBack to clear the property if it ends up setting focus on itself.

Also note, I organized my Action Creators into separate files mostly due to my project is fairly large and I wanted to break them up into more manageable chunks.

import { connect } from 'react-redux';
import MyField from '../presentation/MyField';
import ActionCreator from '../actions/action-creators';

function mapStateToProps(state) {
    return {
        resetFocus: state.form.resetFocus
    }
}

function mapDispatchToProps(dispatch) {
    return {
        clearResetFocus() {
            dispatch(ActionCreator.clearResetFocus());
        }
    }
}

export default connect(mapStateToProps, mapDispatchToProps)(MyField);

Presentation Component

import React, { PropTypes } form 'react';

export default class MyField extends React.Component {
    // don't forget to .bind(this)
    constructor(props) {
        super(props);
        this._handleRef = this._handleRef.bind(this);
    }

    // This is not called on the initial render so
    // this._input will be set before this get called
    componentDidUpdate() {
        if(!this.props.resetFocus) {
            return false;
        }

        if(this.shouldfocus()) {
            this._input.focus();
            this.props.clearResetFocus();
        }
    }

    // When the component mounts, it will save a 
    // reference to itself as _input, which we'll
    // be able to call in subsequent componentDidUpdate()
    // calls if we need to set focus.
    _handleRef(c) {
        this._input = c;
    }

    // Whatever logic you need to determine if this
    // component should get focus
    shouldFocus() {
        // ...
    }

    // pass the _handleRef callback so we can access 
    // a reference of this element in other component methods
    render() {
        return (
            <input ref={this._handleRef} type="text" />
        );
    }
}

Myfield.propTypes = {
    clearResetFocus: PropTypes.func,
    resetFocus: PropTypes.bool
}

Overview

The general idea is that each form field that could have an error and be focused needs to check itself and if it needs to set focus on itself.

There's business logic that needs to happen to determine if the given field is the right field to set focus to. This isn't shown because it will depend on the individual application.

When a form is submitted, that event needs to set the global focus flag resetFocus to true. Then as each component updates itself, it will see that it should check to see if it gets the focus and if it does, dispatch the event to reset focus so other elements don't have to keep checking.

edit As a side note, I had my business logic in a "utilities" file and I just exported the method and called it within each shouldfocus() method.

Cheers!

Killdeer answered 27/4, 2016 at 19:38 Comment(1)
I tried something similar but couldn't make it work. Could you please have a look here? #64543329Crevice
W
17

This is not longer the best answer. As of v0.13, this.refs may not available until AFTER componentDidMount() runs, in some odd cases.

Just add the autoFocus tag to your input field, as FakeRainBrigand showed above.

Wilbertwilborn answered 11/3, 2015 at 2:52 Comment(5)
Multiple <input autofocus> fields won't behave niceKolivas
Of course not. Only one focus per page. If you have multiple autofocuses, you should check your code and intentions.Wilbertwilborn
@Dave's question was about setting focus on an <input> after renderKolivas
On autofocus, is there a way to force the iOS keyboard to open as well?Arni
@RemiSture same questions. Does anyone have a solution to this problem?Gamali
A
14

Ref. @Dave's comment on @Dhiraj's answer; an alternative is to use the callback functionality of the ref attribute on the element being rendered (after a component first renders):

<input ref={ function(component){ React.findDOMNode(component).focus();} } />

More info

Avisavitaminosis answered 26/5, 2015 at 11:49 Comment(2)
When I tried this out, I got: Uncaught TypeError: Cannot read property 'focus' of nullCalliopsis
You have to null check the param, it will be null when the component is not mounted. So a simple component && React.findDomNode.... Read more about it here: facebook.github.io/react/docs/…Luminescence
H
14

Using React Hooks / Functional components with Typescript, you can use the useRef hook with HTMLInputElement as the generic parameter of useRef:

import React, { useEffect, useRef } from 'react';

export default function MyComponent(): JSX.Element {
    const inputReference = useRef<HTMLInputElement>(null);

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

    return (
        <div>
            <input ref={inputReference} />
        </div>
    );
}

Or if using reactstrap, supply inputReference to innerRef instead of ref:

import React, { useEffect, useRef } from 'react';
import { Input } from 'reactstrap';

export default function MyComponent(): JSX.Element {
    const inputReference = useRef<HTMLInputElement>(null);

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

    return (
        <div>
            <Input innerRef={inputReference} />
        </div>
    );
}
Haakon answered 12/9, 2020 at 22:45 Comment(0)
A
13

This is the proper way, how to autofocus. When you use callback instead of string as ref value, it is automatically called. You got your ref available than without the need of touching the DOM using getDOMNode

render: function() {
  return <TextInput ref={(c) => this._input = c} />;
},
componentDidMount: function() {
  this._input.focus();
},
Allantoid answered 12/9, 2016 at 19:24 Comment(2)
what about a controlled form?Anecdote
@pixel67 Also. You can set reference on elements, but also components. But you must be aware of that when working with it. So you wont try to access .value of input, if you set reference on React.Component, that wrappers the html input.Allantoid
C
13

Note that none of these answers worked for me with a material-ui TextField component. Per How to set focus to a materialUI TextField? I had to jump through some hoops to get this to work:

const focusUsernameInputField = input => {
  if (input) {
    setTimeout(() => {input.focus()}, 100);
  }
};

return (
  <TextField
    hintText="Username"
    floatingLabelText="Username"
    ref={focusUsernameInputField}
  />
);
Capstone answered 16/6, 2017 at 11:8 Comment(3)
Seems like if your component is animating in, the call to focus() has to be delayed until the end of the animation.Spikelet
Worked for me, but I used setTimeout(() => {}, 0); just to make cleaner the codeJazzman
window.requestAnimationFrame( ()=> input.focus() ) can be used instead of setTimeout as suggested by Shi1485Flatfoot
Z
10

You don't need getInputDOMNode?? in this case...

Just simply get the ref and focus() it when component gets mounted -- componentDidMount...

import React from 'react';
import { render } from 'react-dom';

class myApp extends React.Component {

  componentDidMount() {
    this.nameInput.focus();
  }

  render() {
    return(
      <div>
        <input ref={input => { this.nameInput = input; }} />
      </div>
    );
  }

}

ReactDOM.render(<myApp />, document.getElementById('root'));
Zaibatsu answered 9/6, 2017 at 16:18 Comment(0)
T
9

You can put that method call inside the render function. Or inside the life cycle method, componentDidUpdate

Tumult answered 6/3, 2015 at 0:14 Comment(1)
componentDidUpdate is what worked for my case. I needed to set the focus on a particular button after render is called.Fidele
G
7

That one worked for me:

<input autoFocus={true} />
Glowworm answered 21/1, 2023 at 13:18 Comment(0)
S
6

I have same problem but I have some animation too, so my colleague suggest to use window.requestAnimationFrame

this is ref attribute of my element:

ref={(input) => {input && window.requestAnimationFrame(()=>{input.focus()})}}
Serene answered 6/9, 2017 at 10:20 Comment(0)
B
5

AutoFocus worked best for me. I needed to change some text to an input with that text on double click so this is what I ended up with:

<input autoFocus onFocus={this.setCaretToEnd} value={this.state.editTodo.value} onDoubleClick={this.updateTodoItem} />

NOTE: To fix the issue where React places the caret at the beginning of the text use this method:

setCaretToEnd(event) {
    var originalText = event.target.value;
    event.target.value = '';
    event.target.value = originalText;
}

Found here: https://coderwall.com/p/0iz_zq/how-to-put-focus-at-the-end-of-an-input-with-react-js

Burgoo answered 31/12, 2017 at 14:22 Comment(0)
S
4

Ben Carp solution in typescript

React 16.8 + Functional component - useFocus hook

export const useFocus = (): [React.MutableRefObject<HTMLInputElement>, VoidFunction] => {
  const htmlElRef = React.useRef<HTMLInputElement>(null);
  const setFocus = React.useCallback(() => {
    if (htmlElRef.current) htmlElRef.current.focus();
  }, [htmlElRef]);

  return React.useMemo(() => [htmlElRef, setFocus], [htmlElRef, setFocus]);
};
Sedda answered 6/2, 2021 at 2:39 Comment(0)
B
3

Warning: ReactDOMComponent: Do not access .getDOMNode() of a DOM node; instead, use the node directly. This DOM node was rendered by App.

Should be

componentDidMount: function () {
  this.refs.nameInput.focus();
}
Barny answered 9/4, 2016 at 22:56 Comment(0)
P
3

To move focus to a newly created element, you can store the element's ID in the state and use it to set autoFocus. e.g.

export default class DefaultRolesPage extends React.Component {

    addRole = ev => {
        ev.preventDefault();
        const roleKey = this.roleKey++;
        this::updateState({
            focus: {$set: roleKey},
            formData: {
                roles: {
                    $push: [{
                        id: null,
                        name: '',
                        permissions: new Set(),
                        key: roleKey,
                    }]
                }
            }
        })
    }

    render() {
        const {formData} = this.state;

        return (
            <GridForm onSubmit={this.submit}>
                {formData.roles.map((role, idx) => (
                    <GridSection key={role.key}>
                        <GridRow>
                            <GridCol>
                                <label>Role</label>
                                <TextBox value={role.name} onChange={this.roleName(idx)} autoFocus={role.key === this.state.focus}/>
                            </GridCol>
                        </GridRow>
                    </GridSection>
                ))}
            </GridForm>
        )
    }
}

This way none of the textboxes get focus on page load (like I want), but when you press the "Add" button to create a new record, then that new record gets focus.

Since autoFocus doesn't "run" again unless the component gets remounted, I don't have to bother unsetting this.state.focus (i.e. it won't keep stealing focus back as I update other states).

Patrimony answered 8/4, 2019 at 2:43 Comment(0)
R
3

Simple solution without autofocus:

<input ref={ref => ref && ref.focus()}
    onFocus={(e)=>e.currentTarget.setSelectionRange(e.currentTarget.value.length, e.currentTarget.value.length)}
    />

ref triggers focus, and that triggers onFocus to calculate the end and set the cursor accordingly.

Rossen answered 24/11, 2020 at 5:14 Comment(0)
C
2

The simplest answer is add the ref="some name" in the input text element and call the below function.

componentDidMount(){
   this.refs.field_name.focus();
}
// here field_name is ref name.

<input type="text" ref="field_name" />
Cocotte answered 28/2, 2017 at 12:11 Comment(0)
C
2

After trying a lot of options above with no success I've found that It was as I was disabling and then enabling the input which caused the focus to be lost.

I had a prop sendingAnswer which would disable the Input while I was polling the backend.

<Input
  autoFocus={question}
  placeholder={
    gettingQuestion ? 'Loading...' : 'Type your answer here...'
  }
  value={answer}
  onChange={event => dispatch(updateAnswer(event.target.value))}
  type="text"
  autocomplete="off"
  name="answer"
  // disabled={sendingAnswer} <-- Causing focus to be lost.
/>

Once I removed the disabled prop everything started working again.

Cyruscyst answered 10/7, 2018 at 8:57 Comment(0)
B
1

Read almost all the answer but didnt see a getRenderedComponent().props.input

Set your text input refs

this.refs.username.getRenderedComponent().props.input.onChange('');

Berck answered 10/7, 2017 at 8:50 Comment(1)
Please further clarify your answer in the context of their code.Explant
I
1

Focus using createRef for functional components

To developers using Functional Components. This seems to suit. Focus happens on inputfield after clicking on the button. I've attached CodeSandbox link too.

import React from 'react';

export default function App() {
  const inputRef = React.createRef();
  return <>
    <input ref={inputRef} type={'text'} />
    <button onClick={() => {if (inputRef.current) { inputRef.current.focus() }}} >
      Click Here
    </button>
  </>
}

https://codesandbox.io/s/blazing-http-hfwp9t

Impel answered 26/4, 2022 at 2:54 Comment(0)
B
1

Set a reference on the input element and then call the focus() method on the ref element:

import { useRef } from "react";

function App() {
  const inputRef = useRef(null);
  return (
    <div>
      <input ref={inputRef} />
      <button onClick={() => {inputRef.current.focus()}}>Focus input</button>
    </div>
  );
}
export default App;
Baccy answered 8/11, 2023 at 15:17 Comment(0)
D
0

Updated version you can check here

componentDidMount() {

    // Focus to the input as html5 autofocus
    this.inputRef.focus();

}
render() {
    return <input type="text" ref={(input) => { this.inputRef = input }} />
})
Dispersoid answered 14/12, 2016 at 12:37 Comment(0)
W
-1

Since there is a lot of reasons for this error I thought that I would also post the problem I was facing. For me, problem was that I rendered my inputs as content of another component.

export default ({ Content }) => {
  return (
  <div className="container-fluid main_container">
    <div className="row">
      <div className="col-sm-12 h-100">
        <Content />                                 // I rendered my inputs here
      </div>
    </div>
  </div>
  );
}

This is the way I called the above component:

<Component Content={() => {
  return (
    <input type="text"/>
  );
}} />
Welcher answered 17/9, 2019 at 15:38 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.