Установка фокуса на ввод после рендеринга
каков способ react установки фокуса на определенном текстовом поле после отрисовки компонента?
документация, похоже, предлагает использовать refs, e.g:
Set ref="nameInput"
в моем поле ввода в функции рендеринга, а затем вызовите:
this.refs.nameInput.getInputDOMNode().focus();
но где я должен это назвать? Я пробовал несколько мест, но не могу заставить его работать.
19 ответов
вы должны сделать его в componentDidMount
и refs callback
вместо. Что-то вроде этого!--8-->
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 является правильным, и для удобства вы можете использовать автофокус опора на вход автоматической фокусировки при монтаже:
<input autoFocus name=...
обратите внимание, что в jsx это autoFocus
(capital F) в отличие от обычного старого html, который не учитывает регистр.
Если вы просто хотите сделать автофокус в 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
Я только что столкнулся с этой проблемой, и я использую react 15.0.1 15.0.2 и я использую синтаксис ES6 и не совсем получил то, что мне нужно от других ответов, так как v. 15 упал несколько недель назад и некоторые из this.refs
свойства были устаревшими и удалены.
в общем, мне нужно было:
- сфокусируйте первый элемент ввода (поля), когда компонент монтируется
- сфокусировать первый вход (поле) элемент с ошибкой (после отправки)
я:
- React Контейнер / Компонент Презентации
- Redux
- React-Маршрутизатор
сфокусировать первый входной элемент
я autoFocus={true}
первый <input />
на странице, чтобы, когда компонент монтируется, он получал фокус.
фокус первого входного элемента с ошибкой
это заняло больше времени и было больше извилистый. Я держу код, который не имеет отношения к решению для краткости.
Redux Store / State
мне нужно глобальное состояние, чтобы знать, должен ли я установить фокус и отключить его, когда он был установлен, поэтому я не продолжаю переустанавливать фокус, когда компоненты перерисовываются (я буду использовать 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()
метод.
Ура!
в документах 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();
}
}} />
);
},
Ref. Комментарий @ Dave к ответу @Dhiraj; альтернативой является использование функции обратного вызова атрибута ref для отображаемого элемента (после того, как компонент сначала отображает):
<input ref={ function(component){ React.findDOMNode(component).focus();} } />
это правильный способ, как автофокус. При использовании обратного вызова вместо строки в качестве значения ref он вызывается автоматически. Вы получили ваш ref доступен, чем без необходимости прикасаться к DOM с помощью getDOMNode
render: function() {
return <TextInput ref={(c) => this._input = c} />;
},
componentDidMount: function() {
this._input.focus();
},
это уже не лучший ответ. Как на версии v0.13, this.refs
может быть недоступно доcomponentDidMount()
выполняется, в некоторых нечетных случаях.
просто добавить autoFocus
тег в поле ввода, как показано выше FakeRainBrigand.
вы можете поместить этот вызов метода внутри функции render. Или внутри метода жизненного цикла, componentDidUpdate
обратите внимание, что ни один из этих ответов работал для меня материал-компонент текстового поля пользовательского интерфейса. Пер Как установить фокус на текстовое поле materialUI? мне пришлось прыгать через некоторые обручи, чтобы заставить это работать:
const focusUsernameInputField = input => {
if (input) {
setTimeout(() => {input.focus()}, 100);
}
};
return (
<TextField
hintText="Username"
floatingLabelText="Username"
ref={focusUsernameInputField}
/>
);
не нужно getInputDOMNode
?? в этом деле...
просто взять ref
и focus()
это когда компонент монтируется -- 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
предупреждение: ReactDOMComponent: не получить доступ .getDOMNode () узла DOM; вместо этого используйте узел напрямую. Этот узел DOM был отображен
App
.
должно быть
componentDidMount: function () {
this.refs.nameInput.focus();
}
самый простой ответ-добавить ref= "некоторое имя" во входном текстовом элементе и вызвать функцию ниже.
componentDidMount(){
this.refs.field_name.focus();
}
// here field_name is ref name.
<input type="text" ref="field_name" />
У меня такая же проблема, но у меня тоже есть анимация, поэтому мой коллега предлагает использовать окно.метод requestAnimationFrame
это атрибут ref моего элемента:
ref={(input) => {input && window.requestAnimationFrame(()=>{input.focus()})}}
прочитайте почти весь ответ, но не видели getRenderedComponent().props.input
установите ввод текста refs
this.refs.username.getRenderedComponent().props.input.onChange('');
попробовав много вариантов выше без успеха, я обнаружил, что это было так, как я был 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.
/>
как только я удалил отключенную опору, все снова начало работать.
обновленная версия, вы можете проверить здесь
componentDidMount() {
// Focus to the input as html5 autofocus
this.inputRef.focus();
}
render() {
return <input type="text" ref={(input) => { this.inputRef = input }} />
})