0

I remove the unnecessary code to make the code clear. The full standalone html file is as follow. When key pressed, I expect the input to lose focus, but actually it doesn't.

If I enclose blur with setTimeout(, 0), it will work. But why the original does not work?

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <script src="https://npmcdn.com/react@15.3.1/dist/react.js"></script>
    <script src="https://npmcdn.com/react-dom@15.3.1/dist/react-dom.js"></script>
    <script src="https://npmcdn.com/babel-core@5.8.38/browser.min.js"></script>
   </head>
<body>
<div id="root">

</div>
<script type="text/babel">
    class HelpBox extends React.Component {
        constructor(props) {
            super(props);
            this.state = {
            };
            window.addEventListener("keydown", this.keyDown.bind(this), false);
        }

        componentDidMount() {
            this.refs.searchWord.focus();
        }

        componentWillUpdate(nextProps, nextState) {
            console.log('will blur', this.refs.searchWord);
            this.refs.searchWord.blur();
        }

        keyDown(e) {
            this.setState({});
        }

        render() {
            return <div>
                <input key="search" ref="searchWord" className="search" type="text"
                />
            </div>
        }
    }

    ReactDOM.render(
            <HelpBox/>,
            document.getElementById('root')
    );
</script>
</body>
</html>

Resolved: I touched DOM in componentWillUpdate, which is then restored by React in render(). That's what React should do LOL.

user147932
  • 23
  • 1
  • 5

1 Answers1

0

the keydown event will trigger blur and focus events as default. Without setTimeout, your this.refs.searchWord.blur() will be executed before the default focus becausethis.refs.searchWord.blur() is in stack. With setTimeout, your this.refs.searchWord.blur() will be put in queue which means your this.refs.searchWord.blur() will be executed after the default focus and other functions in stack. If you are not familiar with stack, queue and event loop, check this video

Phi Nguyen
  • 3,046
  • 14
  • 26
  • Thanks for your reply. But do not think you pin the correct reason for: 1. If I do not use react, blur() in keydown callback is fine. https://jsfiddle.net/oss3jfLy/ – user147932 Sep 06 '16 at 09:00
  • 2. I bind onFocus and onBlur on input element. They are not fired. – user147932 Sep 06 '16 at 09:01
  • those events happen on DOM elements. try `$('.search').onblur` and `$('.search').onfocus` on chrome dev. You will see it trigger events. – Phi Nguyen Sep 06 '16 at 11:15
  • Oh, you are right. These events triggered. The "focus" event triggered after the render() method. This is related to React.js, right? – user147932 Sep 06 '16 at 12:13