当前位置: 首页 > 知识库问答 >
问题:

如果没有setTimeout,react ref with focus()将无法工作(我的示例)

柯建业
2023-03-14

我遇到了这个问题,. point()只适用于setTimeout,如果我把它拿出来,它停止工作问题。

    componentDidMount() {
        React.findDOMNode(this.refs.titleInput).getElementsByTagName('input')[0].focus();
    }

使用setTimeout的示例

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

JXS

<input ref="titleInput" type="text" />

我已经按照这个例子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>
        );
    }

共有2个答案

白烨煜
2023-03-14

在父组件中,我呈现一个包含InputText的primereact对话框:

<Dialog visible={this.state.visible} ...>
  <InputText ref={(nameInp) => {this.nameInp = nameInp}} .../>
  ...
</Dialog>

最初,this.state.visible为false,对话框被隐藏。为了显示对话框,我通过调用showDlg()重新呈现父组件,其中nameInp是对InputText的引用:

showDlg() {
  this.setState({visible:true}, ()=>{
    this.nameInp.element.focus();
  });
}

在某些情况下,您可以简单地使用:

componentDidUpdate(){
  this.nameInp.element.focus();
}

但是,每次(重新)渲染组件时都会调用componentDidUpdate(),包括在InputText隐藏的情况下。

另见:https://reactjs.org/docs/react-component.html#setstate

云卓
2023-03-14

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

ref解析顺序发生了轻微的变化,这样在调用组件的组件的didMount方法后,组件的ref立即可用;只有当您的组件在您的组件的didMount中调用父组件的回调时,才能观察到此更改,这是一种反模式,无论如何都应该避免

这是你的案子。因此,或者您必须将HTML结构分解为单独呈现的元素,如本文所述,然后您将在其自己的componentDidMount回调中访问输入元素;或者你只是坚持你的计时器。

使用componentDidMount可以确保代码仅在调用它的组件被装入时运行(请参阅下面文档中的引用)。

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

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

注意事项

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

findDOMNode()仅适用于已安装的组件(即已放置在DOM中的组件)。如果您尝试在尚未挂载的组件上调用此项(如在尚未创建的组件上调用findDOMNode()中的render()),则会引发异常。

以及来自ref string属性上的文档:

>

  • ref属性分配给从渲染返回的任何内容,例如:

     <input ref="myInput" />
    

    在其他一些代码(通常是事件处理程序代码)中,通过this.refs访问后备实例,如:

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

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

    <ReactInputField
            ref="titleInput"
            autoFocus
            ... />
    

  •  类似资料:
    • 问题内容: 我遇到了这个问题,如果我将其取出并且停止工作,则只能使用该问题。谁能解释我的原因,可能是我做错了,以及如何解决这个问题。 使用setTimeout的示例 JXS 渲染功能 问题答案: 在看到问题的更新之后,我意识到您已经将嵌套的HTML传递给了 render 函数,并且您感兴趣的input元素确实在调用ancestor元素的 componentDidMount 时不可用。如React

    • 我正在从Priming设置fullcalendar事件的工具提示。当我运行代码时,我会在web控制台中看到初始化的工具提示,但当我将鼠标放在事件上时,我看不到它。 我正在用Typescript开发,Priming 7.0。5,6。我正在使用fullcalendar v4。0,我遵循eventRender页面中的工具提示示例。 有我的代码: 贷款组成部分ts 贷款组成部分html 将结果输入我的控制

    • 问题内容: 我知道什么是标记界面以及何时需要使用它。我仍然不清楚一个问题。如果标记接口没有任何方法或主体,那么它在运行时如何工作? 问题答案: 标识接口,可以进行分类

    • 我正在使用Oracle“自含应用程序打包”工具为JavaFX8桌面应用程序创建文件。生成的包文件可以在Ubuntu上毫无问题地安装,但随后应用程序无法运行。该文件的安装方式如下: 重要的是,我正在生成一个不包含JRE的包,经过调查,问题似乎与此有关。生成的文件包含以下行: 如果我编辑它并将路径添加到Java,程序启动时不会出现任何问题。作为一种解决办法,我建议在安装bundle之后,用户运行以下命

    • 我正在尝试实现Spring Security和Angular JS教程中的OAuth2示例,但是在没有JWT的情况下,我遇到了一个问题。示例的代码可以在这里找到。 我对这个例子做了以下修改,试图让它在没有JWT的情况下工作。 /resource/src/main/resources/application。性质 注释了jwt keyValue的属性。 /ui/src/main/resources/

    • 问题内容: 我正在尝试用Java倒计时。 这是我的HTML 而我的JS: 但是由于某种原因,它不会等待超时时间,而是立即执行,以便在刷新页面时立即显示“完成”。我知道它实际上被执行了多次,因为如果我这样做,它会从45开始递减计数。为什么会绕过超时? 问题答案: 执行带有该参数的函数,并将结果传递给。你不要那样 相反,执行一个匿名函数来调用您的函数: