7

I'm trying to autofocus a text input (the input is enabled upon selecting a relevant radio option).

The autofocus works when toggling between options that will enable the text input. However, autofocus fails when switching from an option that disables the text input to an option that enables the text input.

  • In the sample link below:

    • option 1, option 2: disable the text input
    • option 3, option 4: enable the text input
  • Failure case:

    • option 1 is default
    • choose option 3 or option 4
    • input gets enabled
    • autofocus fails (looking for pointer to fix this behaviour)
  • Success case:

    • choose option 3
    • input is enabled
    • switch to option 4
    • input is autoFocussed

sample code for the problem on codesandbox

r0hityadav
  • 83
  • 1
  • 6

2 Answers2

7

This does not work, cause you immediately set it after the setState call, but at this point of lifecycle the component has not re-rendered and the ref to the input is still in a state where it is disabled.

What you need to do is, trigger the focus handling after the component did update in the componentDidUpdate hook.

Something like this (pseudo code)

componentDidUpdate(prevProps, prevState) {

  if (this.state.enabled) {
     this.inputValue.focus();
  }
}

It might be possible that you need additional checks like only focus on a transition from disabled to enabled. This could be achieved by doing something like this:

componentDidUpdate(prevProps, prevState) {
  if (!prevState.enabled && this.state.enabled) {
    this.inputValue.focus();
  }}

Here a link to the updated codesandbox: https://codesandbox.io/s/31RnlkJW4

larrydahooster
  • 4,114
  • 4
  • 40
  • 47
  • Thanks @larrydahooster, is there a (better) way that this could be achieved without the use of refs, just autoFocus maybe? – r0hityadav Jul 06 '17 at 14:32
  • Yeah referencing to chase DeAnda's answer, you can't toggle autofocus as it only affects the component on mount. – larrydahooster Jul 06 '17 at 14:38
4

Just a little extra to add, autoFocus only works on the initial render of the element (basically only when componentDidMount runs). So that's why it's not automatically focusing when you re-enable the input, it's not being unmounted and then re-mounted. To make autoFocus work, you'd need to move the input and disabled input into separate components and conditionally render them based on state.

Chase DeAnda
  • 15,963
  • 3
  • 30
  • 41