如果没有setTimeout(我的例子),使用focus()做出反应是不行的

Bru*_*uce 12 reactjs

我有遇到这样的问题,.focus()只有作品setTimeout,如果我把它拿出来,它停止工作.任何人都可以解释我是什么原因,可能我做错了,我该如何解决问题.

    componentDidMount() {
        React.findDOMNode(this.refs.titleInput).getElementsByTagName('input')[0].focus();
    }
Run Code Online (Sandbox Code Playgroud)

与setTimeout一起工作的例子

componentDidMount() {
    setTimeout(() => {
        React.findDOMNode(this.refs.titleInput).getElementsByTagName('input')[0].focus();
    }, 1);
}
Run Code Online (Sandbox Code Playgroud)

JXS

<input ref="titleInput" type="text" />
Run Code Online (Sandbox Code Playgroud)

我已经按照这个例子React设置了渲染后的输入

渲染功能

render() {
        const {title, description, tagtext, siteName} = (this.state.selected !== undefined) ? this.state.selected : {};
        const hasContentChangedYet = this.hasContentChangedYet(title, description);

        return (
            <div>
                <h2 className={styles.formMainHeader}>Edit Meta-Data Form</h2>
                <table className={styles.formBlock}>
                    <tbody>
                    <tr>
                        <td className={styles.tagEditLabel}>
                            Tag
                        </td>
                        <td className={styles.inputFieldDisableContainer}>
                            {tagtext}
                        </td>
                    </tr>
                    <tr>
                        <td className={styles.tagEditLabel}>
                            Site
                        </td>
                        <td className={styles.inputFieldDisableContainer}>
                            {siteName}
                        </td>
                    </tr>
                    <tr>
                        <td className={styles.tagEditLabel}>
                            Title
                        </td>
                        <td className={styles.inputFieldContainer}>
                            <ReactInputField
                                ref="titleInput"
                                id="title"
                                defaultValue={(title) ? title : ''}
                                onChange={this.onInputChange}
                                placeholder="Title"
                                clearTool={true} />
                        </td>
                    </tr>
                    <tr>
                        <td className={styles.tagEditLabel}>
                            Description
                        </td>
                        <td className={styles.inputFieldContainer}>
                            <ReactInputField
                                id="description"
                                defaultValue={(description) ? description : ''}
                                onChange={this.onInputChange}
                                placeholder="Description"
                                clearTool={true} />
                        </td>
                    </tr>
                    </tbody>
                </table>

                <div className={styles.formFooter}>
                    <button id="save-button" className={styles.saveButton} disabled={!hasContentChangedYet} onClick={() => this.handleSavePressed()}>
                        Save
                    </button>
                    <button id="form-cancel-button" className={styles.cancelButton} onClick={this.actions.form.cancelUpdateToTagData}>
                        Cancel
                    </button>

                </div>
            </div>
        );
    }
Run Code Online (Sandbox Code Playgroud)

tri*_*cot 8

在看到问题的更新后,我意识到你已经将深度嵌套的HTML传递给了渲染函数,并且在对祖先元素进行componentDidMount调用时,你感兴趣的输入元素确实不可用.如React v0.13更改日志中所述:

ref分辨率顺序稍有变化,以便在componentDidMount调用方法后立即获得组件的引用; 只有当你的组件在你的内部调用父组件的回调时才应该观察到这种变化componentDidMount,这是一种反模式,无论如何都应该避免

这是你的情况.因此,无论你的HTML结构分解成单独渲染的元素,如所描述这里,然后你就会访问自己的输入元素componentDidMount回调; 或者你只是坚持你有计时器黑客.

使用componentDidMount确保只有当该组件的代码运行在调用它安装(请参阅从文档报价进一步下跌).

请注意,不鼓励调用React.findDOMNode :

在大多数情况下,您可以将引用附加到DOM节点并完全避免使用findDOMNode.

注意

findDOMNode()是用于访问底层DOM节点的转义填充.在大多数情况下,不鼓励使用此逃生舱,因为它会刺穿组件抽象.

findDOMNode()仅适用于已安装的组件(即已放置在DOM中的组件).如果你试图调用此说尚未安装(如调用组件findDOMNode()render(),目前尚未将要创建的组件)的异常将被抛出.

并从ref字符串属性的文档:

  1. ref属性分配给从render以下所返回的任何内容:

     <input ref="myInput" />
    
    Run Code Online (Sandbox Code Playgroud)
  2. 在其他一些代码(通常是事件处理程序代码)中,通过以下方式访问支持实例this.refs:

    var input = this.refs.myInput;  
    var inputValue = input.value;  
    var inputRect = input.getBoundingClientRect();  
    
    Run Code Online (Sandbox Code Playgroud)

或者,您可以消除代码的需要,并使用JSX autoFocus属性:

<ReactInputField
        ref="titleInput"
        autoFocus
        ... />
Run Code Online (Sandbox Code Playgroud)