렌더링 후 입력 필드에 초점을 설정하는 방법은 무엇입니까?


629

구성 요소가 렌더링 된 후 특정 텍스트 필드에 포커스를 설정하는 반응 방식은 무엇입니까?

문서는 다음과 같은 참조 사용을 제안하는 것 같습니다.

ref="nameInput"render 함수에서 입력 필드에 설정 한 후 다음을 호출하십시오.

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

하지만 어디로 전화해야합니까? 몇 곳을 시도했지만 제대로 작동하지 않습니다.

답변:


668

당신은 그것을해야 componentDidMount하고 refs 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>


107
이것은 정답이지만 다른 버튼을 클릭 할 때까지 구성 요소가 아무것도 렌더링하지 않기 때문에 나에게는 효과가 없었습니다. 이것은 이미 마운트되었으므로 this.refs.nameInput.getDOMNode (). focus (); componentDidMount 대신 componentDidUpdate에서.
Dave

9
왜 element.focus ()가 호출 될 때 커서가 입력의 시작 부분에 놓이나요? 내 응용 프로그램, 크롬, 실제로 <textarea> 에서이 (내가 생각하는 것) 버그를 보았으며 이제 데모를 확인하는 것이 동일합니다.
davnicwil

15
경고 : React.findDOMNode는 더 이상 사용되지 않습니다. 대신 require ( 'react-dom')에서 ReactDOM.findDOMNode를 사용하십시오.
André Pena

5
@HuwDavies 요소 에 ref 콜백 속성 을 사용하여 수행 할 것 같습니다 <input>. 같은 뭔가<input ref={ (component) => ReactDOM.findDOMNode(component).focus() } />
허먼

5
ref = {(input) => {input.focus ()}} 만 사용하지 않습니까? 이 솔루션은 저에게 잘 작동합니다.
HCLiu

840

@Dhiraj의 답변은 정확하며 편의상 autoFocus 소품을 사용하여 마운트 할 때 입력에 자동으로 초점을 맞출 수 있습니다.

<input autoFocus name=...

jsx에서는 autoFocus대소 문자를 구분하지 않는 일반 오래된 HTML과 달리 (자본 F)입니다.


95
jsx에서 대소 문자를 구분하지 않는 일반 오래된 html과 달리 자동 F ocus (자본 F)입니다.
prauchfuss

8
아주 좋은, 긴 과일없는 검색 후 여기에 왔습니다 :) 참고-React.DOM.input ({type : 'text', defaultValue : content, autoFocus : true, onFocus : function (e) {e.target. select ();}})
mlo55

4
autoFocus는 첫 페이지 렌더링에서만 작동합니다. codepen.io/ericandrewlewis/pen/PbgwqJ?editors=1111을 참조하십시오 . 입력은 3 초 후에 초점이 맞춰져야 합니다.
Eric Andrew Lewis

45
이 방법의 경우 +1 이것은 단지 HTML5 신뢰할 사용하지 않는 언급이의 가치 autofocus속성은 실제로 사용 focus()에 마운트 DOM에react-dom 꽤 신뢰할 수있는, 그래서.
Aaron Beall

3
"편의를 위해"뿐만 아니라 구성 요소가 기능적 구성 요소 인 경우에도.
phillyslick

167

React 0.15 에서 가장 간결한 방법은 다음과 같습니다.

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

5
또한 자동 렌더를 사용하지 않고 초기 렌더 외부의 시나리오를 처리합니다.
Matt Stannett

질문, 입력이 언제 거짓입니까? 화살표 함수 내부의 표현식을 참조하고 있습니다.
JaeGeeTee

2
@ JaeGeeTee 구성 요소가 마운트 될 때까지 및 / 또는 마운트가 해제 된 후에는 null입니다 (어떤 경우인지는 확실하지 않습니다).
Ilya Semenov

12
이것의 유일한 문제는 원하지 않는 재 렌더링에 대한 입력에 집중한다는 것입니다.
Jaroslav Benc

내 경우에는 작동하지 않습니다 ( Ant Design 입력 구성 요소 사용)
vsync

118

마운트에 집중

요소를 마운트 (초기 렌더링) 할 때 요소에 초점을 맞추려면 autoFocus 속성을 사용하면됩니다.

<input type="text" autoFocus />

다이나믹 포커스

포커스를 동적으로 제어하려면 일반 함수를 사용하여 구성 요소에서 구현 세부 정보를 숨 깁니다.

React 16.8 + 기능적 구성 요소-초점 후크 사용

const FocusDemo = () => {

    const [inputRef, setInputFocus] = useFocus()

    return (
        <> 
            <button onClick={setInputFocus} >
               FOCUS
            </button>
            <input ref={inputRef} />
        </>
    )

}
const useFocus = () => {
    const htmlElRef = useRef(null)
    const setFocus = () => {htmlElRef.current &&  htmlElRef.current.focus()}

    return [ htmlElRef, setFocus ] 
}

전체 데모

반응 16.3 + 클래스 구성 요소-활용

class App extends Component {
  constructor(props){
    super(props)
    this.inputFocus = utilizeFocus()
  }

  render(){
    return (
      <> 
          <button onClick={this.inputFocus.setFocus}>
             FOCUS
          </button>
          <input ref={this.inputFocus.ref}/>
      </>
    )
  } 
}
const utilizeFocus = () => {
    const ref = React.createRef()
    const setFocus = () => {ref.current &&  ref.current.focus()}

    return {setFocus, ref} 
}

전체 데모


2
이 답변에는 React Hooks에 대한 올바른 접근 방법이 포함되어 있습니다. 감독자! TypeScript에서는 그대로 형식 검사를하지 않지만 배열 대신 (1) (htmlElRef.current as any).focus()및 (2) return {htmlElRef, setFocus}를 작동시키는 한 가지 방법 입니다.
Ahmed Fasih 1

@ AhmedFasih, 나는 당신이 말하는 것을 알고 있지만,이 스레드의 범위를 벗어난 것으로 생각합니다. 객체를 반환하면 변수의 이름을 제어하기가 더 어려워 useFocus져 여러 요소에 사용하려는 경우 문제가 될 수 있습니다 .
벤 잉어

8
여기는 useFocusTypescript 로 작성되었습니다. gist.github.com/carpben/de968e377cbac0ffbdefe1ab56237573
벤 잉어

2
맛있고 고맙습니다 !!! 와우, 나는 const 어설 션 ( as const당신이 가진 것) 에 대해 몰랐습니다 .
Ahmed Fasih

@BenCarp 후크에 대한 작은 제안은 set같은 두 번째 위치에 넣는 것이 좋습니다 const [inputRef, setInputFocus] = useFocus(). 이것은 useState와 더 일치합니다. 먼저 물체, 그 물체의 세터
Rubanov

59

React에서 자동 초점을 만들고 싶다면 간단합니다.

<input autoFocus type="text" />

해당 코드를 어디에 둘 것인지 알고 싶다면 componentDidMount ()에 답하십시오.

v014.3

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

대부분의 경우 참조를 DOM 노드에 첨부하고 findDOMNode를 전혀 사용하지 않아도됩니다.

https://facebook.github.io/react/docs/top-level-api.html#reactdom.finddomnode 에서 API 문서를 읽으십시오.


9
그리고 그것을 대문자로 기억하십시오 F! (응답자가 아닌 자기 자신과 타인에게 메모하십시오.)
2540625

29

React 16.3 은 컴포넌트 생성자에 참조를 생성하고 아래와 같이 사용하여이를 처리하는 편리한 방법을 새로 추가했습니다.

class MyForm extends Component {
  constructor(props) {
      super(props);

      this.textInput = React.createRef();
  }

  componentDidMount() {
    this.textInput.current.focus(); // one important change here is that we need to access the element via current.
  }

  render() {
    // instead of using arrow function, the created ref can be used directly.
    return(
      <div>
        <input ref={this.textInput} />
      </div>
    );
  }
}

자세한 내용 은 React 블로그 에서이 기사 를 확인할 수 있습니다 .

최신 정보:

반작용부터 출발 16.8 , useRef후크는 동일한 결과를 달성하기 위해 기능 요소에 사용될 수있다 :

import React, { useEffect, useRef } from 'react';

const MyForm = () => {
  const textInput = useRef(null);

  useEffect(() => {
    textInput.current.focus();
  }, []);

  return (
    <div>
      <input ref={textInput} />
    </div>
  );
};

26

반응 난 그냥이 문제에 달려 내가 사용하고 15.0.1 15.0.2을 내가 ES6 구문을 사용하고 있는데 꽤 15 절은 몇 주 전에 떨어 이후로는 다른 답변에서 필요한 것을 얻을하지 않았다 this.refs특성을 더 이상 사용되지 않고 제거되었습니다 .

일반적으로 필요한 것은 다음과 같습니다.

  1. 구성 요소가 장착 될 때 첫 번째 입력 (필드) 요소의 초점을 맞 춥니 다
  2. 오류가있는 첫 번째 입력 (필드) 요소에 초점을 맞 춥니 다 (제출 후)

나는 사용하고있다 :

  • 반응 컨테이너 / 프레젠테이션 구성 요소
  • 리덕스
  • 반응 라우터

첫 번째 입력 요소에 집중

페이지 autoFocus={true}의 첫 번째 부분 <input />을 사용 하여 구성 요소가 마운트 될 때 포커스를 얻습니다.

오류가있는 첫 번째 입력 요소에 초점 맞추기

시간이 더 걸리고 더 복잡해졌습니다. 간결한 솔루션과 관련이없는 코드를 보관하고 있습니다.

Redux Store / 주

포커스를 설정해야하는지, 포커스를 설정해야하는지 확인하려면 전역 상태가 필요하므로 구성 요소를 다시 렌더링 할 때 포커스를 다시 설정하지 않습니다 ( componentDidUpdate()포커스 설정을 확인하는 데 사용합니다). )

응용 프로그램에 적합하게 설계 될 수 있습니다.

{
    form: {
        resetFocus: false,
    }
}

컨테이너 구성 요소

구성 요소 resetfocus에 포커스를 설정 하면 속성을 설정하고 속성을 지우려면 콜백 이 필요 합니다.

또한 내 프로젝트는 상당히 크기 때문에 액션 크리에이터를 별도의 파일로 구성했으며 더 관리하기 쉬운 덩어리로 나누고 싶었습니다.

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 로 설정해야 합니다. 그런 다음 각 구성 요소가 자체적으로 업데이트 될 때 포커스가 있는지 확인하고, 그렇다면 포커스를 재설정하기 위해 이벤트를 전달하여 다른 요소가 계속 확인하지 않아도됩니다.

편집 보조 노트로서, 나는 "유틸리티"파일에 내 비즈니스 로직을했고 난 그냥 각 내에서 방법을 수출하고 호출 shouldfocus()하는 방법.

건배!


25

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
나는 이것이 특정 시나리오에서 그것을하는 좋은 방법이라고 생각합니다.
fabio.sussetto

나는 autofocus마운트 할 필요가 없었고 값을 입력 할 때 요소가 계속 집중되도록했습니다. 이것은 해당 시나리오에 완벽하게 작동했습니다. (반응 15 사용)
매트 파 릴라

13

더 이상 최선의 대답은 아닙니다. v0.13부터는 이상한 경우 this.refsAFTER componentDidMount()가 실행될 때까지 사용하지 못할 수 있습니다 .

autoFocusFakeRainBrigand가 위에 표시된 것처럼 입력 필드에 태그를 추가하기 만하면 됩니다.


4
여러 <input autofocus>필드가 제대로 작동하지 않습니다
ᆼ ᆺ ᆼ

4
당연히 아니지. 페이지 당 하나의 초점. 자동 초점이 여러 개인 경우 코드와 의도를 확인해야합니다.
GAEfan

2
<input>
@Dave

1
자동 초점에서 iOS 키보드를 강제로 열 수있는 방법이 있습니까?
Remi Sture

1
@RemiSture 같은 질문입니다. 누구 든지이 문제에 대한 해결책이 있습니까?
Nam Lê Quý

12

참조 @Dhiraj의 답변에 대한 @Dave의 의견; 대안은 (컴포넌트가 처음 렌더링 된 후) 렌더링되는 요소에서 ref 속성의 콜백 기능을 사용하는 것입니다.

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

더 많은 정보


나는이 아웃했을 때, 내가 가지고 :Uncaught TypeError: Cannot read property 'focus' of null
reectrix을

1
매개 변수를 널 점검해야하며, 구성 요소가 마운트되지 않으면 널이됩니다. 간단 component && React.findDomNode...합니다. 자세한 내용은 다음을 참조하십시오 : facebook.github.io/react/docs/…
Wiklander 당

12

이것이 자동 초점을 맞추는 올바른 방법입니다. 문자열 대신 콜백을 참조 값으로 사용하면 자동으로 호출됩니다. 사용하여 DOM을 만질 필요가없는 것보다 ref를 사용할 수 있습니다.getDOMNode

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

2
통제 된 양식은 어떻습니까?
pixel 67

@ pixel67도. 요소뿐만 아니라 구성 요소에 대한 참조를 설정할 수 있습니다. 그러나 작업 할 때이를 알고 있어야합니다. 따라서 React.Component에 참조를 설정하면 html 입력을 래퍼하는 입력 값에 액세스하려고하지 않습니다.
Pavel Hasala

10

이 답변 중 어느 것도 material-ui TextField 구성 요소 와 함께 작동하지 않았습니다 . 당 방법을 설정 한 포커스에 materialUI 텍스트 필드에? 이 작업을 수행하기 위해 농구 대를 뛰어 넘어야했습니다.

const focusUsernameInputField = input => {
  if (input) {
    setTimeout(() => {input.focus()}, 100);
  }
};

return (
  <TextField
    hintText="Username"
    floatingLabelText="Username"
    ref={focusUsernameInputField}
  />
);

2
구성 요소가 애니메이션 focus()인 경우 애니메이션이 끝날 때까지 호출 이 지연되어야합니다.
adriendenat

9

해당 메소드 호출을 render 함수 안에 넣을 수 있습니다. 또는 수명주기 방법 안에서componentDidUpdate


1
componentDidUpdate는 제 경우에 효과적이었습니다. 렌더링이 호출 된 후 특정 버튼에 포커스를 설정해야했습니다.
FariaC

8

당신은 필요하지 않습니다 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'));

5

자동 초점이 가장 효과적이었습니다. 더블 클릭하면 해당 텍스트가있는 입력으로 일부 텍스트를 변경해야하므로 이것이 결국 끝났습니다.

<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


3

같은 문제가 있지만 애니메이션도 있으므로 동료가 window.requestAnimationFrame을 사용하도록 제안합니다.

이것은 내 요소의 ref 속성입니다.

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

2

경고 : ReactDOMComponent : DOM 노드의 .getDOMNode ()에 액세스하지 마십시오. 대신 노드를 직접 사용하십시오. 이 DOM 노드는에 의해 렌더링되었습니다 App.

해야한다

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

2

가장 간단한 대답은 입력 텍스트 요소에 ref = "some name"을 추가하고 아래 함수를 호출하는 것입니다.

componentDidMount(){
   this.refs.field_name.focus();
}
// here field_name is ref name.

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

2

새로 작성된 요소로 초점을 이동하려면 요소의 ID를 상태에 저장하고이를 사용하여 설정하십시오 autoFocus. 예 :

export default class DefaultRolesPage extends React.Component {

    addRole = ev => {
        ev.preventDefault();
        const roleKey = this.roleKey++;
        this::updateState({
            focus: {$set: roleKey},
            formData: {
                roles: {
                    $push: [{
                        id: null,
                        name: '',
                        permissions: new Set(),
                        key: roleKey,
                    }]
                }
            }
        })
    }

    render() {
        const {formData} = this.state;

        return (
            <GridForm onSubmit={this.submit}>
                {formData.roles.map((role, idx) => (
                    <GridSection key={role.key}>
                        <GridRow>
                            <GridCol>
                                <label>Role</label>
                                <TextBox value={role.name} onChange={this.roleName(idx)} autoFocus={role.key === this.state.focus}/>
                            </GridCol>
                        </GridRow>
                    </GridSection>
                ))}
            </GridForm>
        )
    }
}

이런 식으로 텍스트 상자 중 어느 것도 페이지로드에 초점을 두지 않습니다 (예 : 원하는대로). "추가"단추를 눌러 새 레코드를 만들면 새 레코드가 포커스를 갖습니다.

autoFocus구성 요소가 다시 마운트되지 않으면 다시 "실행"되지 않기 때문에 설정을 this.state.focus취소 할 필요가 없습니다 (즉, 다른 상태를 업데이트 할 때 포커스를 계속 훔치지 않습니다).


1

거의 모든 답변을 읽었지만 보지 못했습니다. getRenderedComponent().props.input

텍스트 입력 심판 설정

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


코드의 맥락에서 답변을 명확하게 설명하십시오.
Jimmy Smith

1

어떤 성공보다 많은 옵션을 시도 후 나는이었다 그것은 이었다는 것을 발견 한 disablingenabling초점을 야기 입력이 손실 될 수 있습니다.

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.
/>

비활성화 된 소품을 제거하면 모든 것이 다시 작동하기 시작했습니다.


0

여기에서 확인할 수있는 업데이트 된 버전

componentDidMount() {

    // Focus to the input as html5 autofocus
    this.inputRef.focus();

}
render() {
    return <input type="text" ref={(input) => { this.inputRef = input }} />
})

0

이 오류에 대한 많은 이유가 있기 때문에 내가 직면 한 문제를 게시 할 것이라고 생각했습니다. 나에게 문제는 입력을 다른 구성 요소의 내용으로 렌더링한다는 것입니다.

export default ({ Content }) => {
  return (
  <div className="container-fluid main_container">
    <div className="row">
      <div className="col-sm-12 h-100">
        <Content />                                 // I rendered my inputs here
      </div>
    </div>
  </div>
  );
}

이것이 위의 구성 요소를 호출 한 방식입니다.

<Component Content={() => {
  return (
    <input type="text"/>
  );
}} />

0

업데이트 된 구문에 따라 사용할 수 있습니다 this.myRref.current.focus()

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.