Search code examples
javascriptreactjsreact-bootstrap

autoFocus on input when opening modal does not work - React Bootstrap


I have a modal that has 3 components. Each component represents a stage, so for example the first component is inputing the user's first name when the user click next, and it will go to the next component, which is inputing address and then user clicks next and it will take the user to the last stage, inputing a nickname. On every input element from the components, it will have an autoFocus. So far in the last two components, the inputs have an autoFocus except for the first component.

Not sure why the first doesn't have it, when I initialise the modal I see the input doesn't have the autoFocus, then I hit next then the second component input has it and I go back to the first component - hit the back button - then I see the input from the first component has an autoFocus. Very strange, I've been trying so many way to resolve this, from setting autoFocus={false} to the modal, creating a ref for the first input but still not working.

It looks like it's an issue with the modal, where it's initialized the focus is somewhere but not on the input. Has anyone encountered this issue?

Example (pseudo) code

//Component Hosting the modal

render(){

    if(this.state.modal_stage === 1){
        <FirstName />
    }else if(this.state.modal_stage === 2){
        <LasgtName />

    }else if(this.state.modal_stage === 3){
        <NickName />
    }
    return(

        <Modal 
            dialogClassName="locationModal customModal"
            show={this.state.modalShow} onHide={this.hideModal}
            autoFocus="false">
            <Modal.Header>
                <div className="closeModal" onClick={this.hideModal}></div>
            </Modal.Header>

            <Modal.Body>

                { current_stage}

            </Modal.Body>

            <Modal.Footer>
                {backButton}
                {nextButton}
            </Modal.Footer>

        </Modal>


    );
}


//<FirstName /> component

constructor(props){
    super(props)
    this.inputRef = React.createRef();
}

componentDidMount(){
    this.inputRef.current.focus();
}

....

render(){


    return(
        <div>
            <input type="text" placeholder="firstName" ref={this.inputRef}/>
        </div>
    );
}

Your help will be appreciated!!

Note:

I tried to set this autoFocus="false" to autoFocus={false} in the modal but the issue still remains.


Solution

  • Found out a solution that will fix your problem. You can add a little timeout for your component to focus on your input. This should fix your issue.

    class FirstInput extends React.Component {
      constructor(props) {
        super(props);
        this.innerRef = React.createRef();
      }
    
      componentDidMount() {
        // Add a timeout here
        setTimeout(() => {
          this.innerRef.current.focus();
        }, 1)
      }
    
      render() {
        return <input ref={this.innerRef} />;
      }
    }
    

    This is a working example: https://codesandbox.io/s/react-bootstrap-autofocus-efkve?fontsize=14