react ref with focus() doesn't work without setTimeout (my example)

后端 未结 2 896
青春惊慌失措
青春惊慌失措 2020-12-18 21:12

I have encounter this problem, the .focus() only works with setTimeout if i take it out and it stop working. can anyone explain me what\'s the reas

2条回答
  •  醉梦人生
    2020-12-18 21:51

    After seeing the update to the question, I realise that you have deeply nested HTML passed to the render function, and the input element of your interest will indeed not be available at the time of the componentDidMount call on the ancestor element. As stated in the React v0.13 Change Log:

    ref resolution order has changed slightly such that a ref to a component is available immediately after its componentDidMount method is called; this change should be observable only if your component calls a parent component's callback within your componentDidMount, which is an anti-pattern and should be avoided regardless

    This is your case. So either you have to break down the HTML structure into separately rendered elements, as described here, and then you would access the input element in its own componentDidMount callback; or you just stick with the timer hack you have.

    Use of componentDidMount makes sure the code runs only when the component on which it is called is mounted (see quote from docs further down).

    Note that calling React.findDOMNode is discouraged:

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

    Note

    findDOMNode() is an escape hatch used to access the underlying DOM node. In most cases, use of this escape hatch is discouraged because it pierces the component abstraction.

    findDOMNode() only works on mounted components (that is, components that have been placed in the DOM). If you try to call this on a component that has not been mounted yet (like calling findDOMNode() in render() on a component that has yet to be created) an exception will be thrown.

    And from the docs on the ref string attribute:

    1. Assign a ref attribute to anything returned from render such as:

       
      
    2. In some other code (typically event handler code), access the backing instance via this.refs as in:

      var input = this.refs.myInput;  
      var inputValue = input.value;  
      var inputRect = input.getBoundingClientRect();  
      

    Alternatively, you could eliminate the need of the code, and use the JSX autoFocus attribute:

    
    

提交回复
热议问题