development

렌더링 후 입력에 초점 설정

big-blog 2020. 2. 10. 22:18
반응형

렌더링 후 입력에 초점 설정


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

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

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

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

그러나 나는 이것을 어디로 불러야합니까? 몇 곳을 시도했지만 제대로 작동하지 않습니다.


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


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

<input autoFocus name=...

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


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

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

마운트에 집중

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

<input type="text" autoFocus />

인터랙티브 포커스

포커스를 조건부로 제어하려면 함수 구성을 사용하여 구성 요소에서 dom 및 브라우저 구현 세부 사항을 숨기십시오.

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

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

    return [ htmlElRef, setFocus ] 
}

그런 다음 모든 기능 구성 요소에서 사용하십시오.

const FocusDemo = () => {

    const [value, setValue] = useState("")
    const [inputRef, setInputFocus] = useFocus()
    const [btnRef, setBtnFocus] = useFocus()

    return (
        <> {/* React.Fragment */}

            <input
                value={value}
                onChange={(e)=>{
                    setValue(e.target.value)
                    if ( some logic ){ setBtnFocus() }
                }}
                ref={inputRef}
            />

            <button 
               onClick={setInputFocus}
               ref={btnRef}
            >
               Refocus
            </button>

        </>
    )

}

데모

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

const utilizeFocus = () => {
    const ref = React.createRef()
    const setFocus = () => {ref.current &&  ref.current.focus()}

    return {setFocus, ref} 
}

그런 다음 모든 클래스 구성 요소에서 사용하십시오.

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

  render(){
    return (
      <> {/* React.Fragment */}

          <input
              value={value}
              onChange={(e)=>{
                  setValue(e.target.value)
                  if ( some logic ){ this.BtnFocus.setFocus() }
              }}
              ref={this.input1Focus.ref}
          />

          <button 
             onClick={this.input1Focus.setFocus()}
             ref={this.BtnFocus.ref}
          >
             Refocus
          </button>

      </>
    )
  } 
}

데모


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 문서를 읽으십시오.


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

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

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

나는 사용하고있다 :

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

첫 번째 입력 요소에 집중

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

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

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

Redux Store / 주

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

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

{
    form: {
        resetFocus: false,
    }
}

컨테이너 구성 요소

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

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

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()하는 방법.

건배!


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();
        }
      }} />
    );
  },

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>
  );
};

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

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


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

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

더 많은 정보


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

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

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


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

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

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

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

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

<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


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

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

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

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

해야한다

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

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

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

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

새로 작성된 요소로 초점을 이동하려면 요소의 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(I 다른 상태를 업데이트 할 때 즉, 그것은 초점 등을 훔치는 유지되지 않습니다).


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

텍스트 입력 심판 설정

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


어떤 성공보다 많은 옵션을 시도 후 나는이었다 그것은 이었다는 것을 발견 한 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.
/>

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


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

componentDidMount() {

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

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

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

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"/>
  );
}} />

참고 URL : https://stackoverflow.com/questions/28889826/set-focus-on-input-after-render



반응형