首页 文章

渲染后将焦点设置在输入上

提问于
浏览
396

在呈现组件后,将焦点设置在特定文本字段上的反应方式是什么?

文档似乎建议使用refs,例如:

在render函数的输入字段上设置 ref="nameInput" ,然后调用:

this.refs.nameInput.getInputDOMNode().focus();

但我应该在哪里打电话呢?我尝试了几个地方,但我无法让它工作 .

19 回答

  • 49

    React文档现在有一个部分 . https://facebook.github.io/react/docs/more-about-refs.html#the-ref-callback-attribute

    render: function() {
      return (
        <TextInput
          ref={function(input) {
            if (input != null) {
              input.focus();
            }
          }} />
        );
      },
    
  • 1

    更新后的版本可以查看here

    componentDidMount() {
    
        // Focus to the input as html5 autofocus
        this.inputRef.focus();
    
    }
    render() {
        return <input type="text" ref={(input) => { this.inputRef = input }} />
    })
    
  • 10

    最简单的答案是在输入文本元素中添加ref =“some name”并调用以下函数 .

    componentDidMount(){
       this.refs.field_name.focus();
    }
    // here field_name is ref name.
    
    <input type="text" ref="field_name" />
    
  • 605

    你应该在 componentDidMountrefs callback中这样做 . 像这样的东西

    componentDidMount(){
       this.nameInput.focus(); 
    }
    
    class App extends React.Component{
      componentDidMount(){
        this.nameInput.focus();
      }
      render() {
        return(
          <div>
            <input 
              defaultValue="Won't focus" 
            />
            <input 
              ref={(input) => { this.nameInput = input; }} 
              defaultValue="will focus"
            />
          </div>
        );
      }
    }
        
    ReactDOM.render(<App />, document.getElementById('app'));
    
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.3.1/react.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.3.1/react-dom.js"></script>
    <div id="app"></div>
    
  • 10

    @ Dhiraj的答案是正确的,为方便起见,您可以使用autoFocus道具在安装时自动聚焦输入:

    <input autoFocus name=...
    

    请注意,在jsx中它是 autoFocus (大写字母F),而不像普通的旧HTML那样不区分大小写 .

  • 0

    您可以将该方法调用放在render函数中 . 或者在生命周期方法中, componentDidUpdate

  • 1

    请注意,这些答案都不适用于material-ui TextField component . 每How to set focus to a materialUI TextField?我不得不跳过一些箍来让它工作:

    const focusUsernameInputField = input => {
      if (input) {
        setTimeout(() => {input.focus()}, 100);
      }
    };
    
    return (
      <TextField
        hintText="Username"
        floatingLabelText="Username"
        ref={focusUsernameInputField}
      />
    );
    
  • 126

    如果你只想在React中进行自动对焦,那很简单 .

    <input autoFocus type="text" />
    

    如果您只是想知道放置该代码的位置,那么答案就在componentDidMount()中 .

    v014.3

    componentDidMount() {
        this.refs.linkInput.focus()
    }
    

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

    在这里阅读API文档:https://facebook.github.io/react/docs/top-level-api.html#reactdom.finddomnode

  • 6

    As of React 0.15 ,最简洁的方法是:

    <input ref={input => input && input.focus()}/>
    
  • 24

    你不需要 getInputDOMNode ??在这种情况下...

    只需在组件安装时获取 reffocus() - componentDidMount ...

    import React from 'react';
    import { render } from 'react-dom';
    
    class myApp extends React.Component {
    
      componentDidMount() {
        this.nameInput.focus();
      }
    
      render() {
        return(
          <div>
            <input ref={input => { this.nameInput = input; }} />
          </div>
        );
      }
    
    }
    
    ReactDOM.render(<myApp />, document.getElementById('root'));
    
  • 2

    阅读几乎所有的答案,但没有看到 getRenderedComponent().props.input

    设置文本输入引用

    this.refs.username.getRenderedComponent().props.input.onChange('');

  • 9

    AutoFocus最适合我 . 我需要在双击时将一些文本更改为带有该文本的输入,这样我才最终得到:

    <input autoFocus onFocus={this.setCaretToEnd} value={this.state.editTodo.value} onDoubleClick={this.updateTodoItem} />
    

    注意:要解决React将插入符号放在文本开头的问题,请使用以下方法:

    setCaretToEnd(event) {
        var originalText = event.target.value;
        event.target.value = '';
        event.target.value = originalText;
    }
    

    在此处找到:https://coderwall.com/p/0iz_zq/how-to-put-focus-at-the-end-of-an-input-with-react-js

  • 22

    这是正确的方法,如何自动对焦 . 当您使用回调而不是字符串作为ref值时,会自动调用它 . 你得到了你的参考,而不需要使用 getDOMNode 触摸DOM

    render: function() {
      return <TextInput ref={(c) => this._input = c} />;
    },
    componentDidMount: function() {
      this._input.focus();
    },
    
  • 2

    这不再是最佳答案 . 从v0.13开始, this.refs 可能在AFTER componentDidMount() 运行之前无法使用,在某些奇怪的情况下 .

    只需将 autoFocus 标记添加到输入字段,如上面的FakeRainBrigand所示 .

  • 6

    我有同样的问题,但我也有一些动画,所以我的同事建议使用window.requestAnimationFrame

    这是我的元素的ref属性:

    ref={(input) => {input && window.requestAnimationFrame(()=>{input.focus()})}}
    
  • 3

    在尝试了上面的很多选项但没有成功之后我发现它就像我 disabling 然后 enabling 导致焦点丢失的输入 .

    我有一个道具 sendingAnswer ,它会在我查询后端时禁用输入 .

    <Input
      autoFocus={question}
      placeholder={
        gettingQuestion ? 'Loading...' : 'Type your answer here...'
      }
      value={answer}
      onChange={event => dispatch(updateAnswer(event.target.value))}
      type="text"
      autocomplete="off"
      name="answer"
      // disabled={sendingAnswer} <-- Causing focus to be lost.
    />
    

    一旦我删除了禁用的道具,一切都开始工作了 .

  • 458

    我刚刚遇到了这个问题而且我正在使用react 15.0.1 15.0.2而且我从其他答案中得到了我需要的东西,因为自从v.15在几周之前掉了一些this.refs properties were deprecatedremoved .

    一般来说,我需要的是:

    • 在组件安装时,聚焦第一个输入(字段)元素

    • 将第一个输入(字段)元素聚焦并显示错误(提交后)

    我正在使用:

    • React容器/演示组件

    • Redux

    • React-Router

    聚焦第一个输入元素

    我在页面的第一个 <input /> 上使用 autoFocus={true} ,这样当组件安装时,它将获得焦点 .

    使用错误聚焦第一个输入元素

    这花费的时间更长,更复杂 . 为了简洁,我保留了与解决方案无关的代码 .

    Redux商店/州

    我需要一个全局状态来知道我是否应该设置焦点并在设置时禁用它,所以我不会't keep re-setting focus when the components re-render (I'将使用 componentDidUpdate() 来检查设置焦点 . )

    这可以按照您认为适合您的应用程序进行设计 .

    {
        form: {
            resetFocus: false,
        }
    }
    

    容器组件

    组件需要设置 resetfocus 属性,并且如果最终将焦点设置为自身,则需要使用callBack清除属性 .

    还要注意,我将Action Creators组织成单独的文件,主要是因为我的项目相当大,我想将它们分解成更易于管理的块 .

    import { connect } from 'react-redux';
    import MyField from '../presentation/MyField';
    import ActionCreator from '../actions/action-creators';
    
    function mapStateToProps(state) {
        return {
            resetFocus: state.form.resetFocus
        }
    }
    
    function mapDispatchToProps(dispatch) {
        return {
            clearResetFocus() {
                dispatch(ActionCreator.clearResetFocus());
            }
        }
    }
    
    export default connect(mapStateToProps, mapDispatchToProps)(MyField);
    

    演示组件

    import React, { PropTypes } form 'react';
    
    export default class MyField extends React.Component {
        // don't forget to .bind(this)
        constructor(props) {
            super(props);
            this._handleRef = this._handleRef.bind(this);
        }
    
        // This is not called on the initial render so
        // this._input will be set before this get called
        componentDidUpdate() {
            if(!this.props.resetFocus) {
                return false;
            }
    
            if(this.shouldfocus()) {
                this._input.focus();
                this.props.clearResetFocus();
            }
        }
    
        // When the component mounts, it will save a 
        // reference to itself as _input, which we'll
        // be able to call in subsequent componentDidUpdate()
        // calls if we need to set focus.
        _handleRef(c) {
            this._input = c;
        }
    
        // Whatever logic you need to determine if this
        // component should get focus
        shouldFocus() {
            // ...
        }
    
        // pass the _handleRef callback so we can access 
        // a reference of this element in other component methods
        render() {
            return (
                <input ref={this._handleRef} type="text" />
            );
        }
    }
    
    Myfield.propTypes = {
        clearResetFocus: PropTypes.func,
        resetFocus: PropTypes.bool
    }
    

    概述

    一般的想法是,每个可能有错误并被集中的表单字段需要检查自己以及是否需要将注意力集中在自身上 .

    需要发生业务逻辑以确定给定字段是否是设置焦点的正确字段 . 这没有显示,因为它取决于个人应用 .

    提交表单时,该事件需要将全局焦点标志 resetFocus 设置为true . 然后每个组件更新本身,它将看到它应该检查它是否得到焦点,如果它,它调度事件重置焦点,以便其他元素不必继续检查 .

    编辑作为旁注,我在"utilities"文件中有我的业务逻辑,我只是导出了方法并在每个 shouldfocus() 方法中调用它 .

    干杯!

  • 2

    参考 . @Dave对@ Dhiraj答案的评论;另一种方法是在正在渲染的元素上使用ref属性的回调功能(在组件首次渲染之后):

    <input ref={ function(component){ React.findDOMNode(component).focus();} } />
    

    More info

  • 7

    警告:ReactDOMComponent:不访问DOM节点的.getDOMNode();相反,直接使用节点 . 这个DOM节点由App呈现 .

    应该

    componentDidMount: function () {
      this.refs.nameInput.focus();
    }
    

相关问题