Я только столкнулся с этой проблемой, и я использую реагировать 15.0.1 15.0.2, и я использую синтаксис ES6 и не совсем получил то, что мне было нужно из других ответов, так как v.15 упала несколько недель назад и некоторые this.refs
свойства были объявлены устаревшими и удалены .
В общем то, что мне было нужно, было:
- Фокус первого элемента ввода (поля), когда компонент монтируется
- Фокус первого элемента ввода (поля) с ошибкой (после отправки)
Я использую:
- Реагировать Контейнер / Презентация Компонент
- Redux
- Реагировать-маршрутизатор
Сосредоточиться на первом элементе ввода
Я использовал autoFocus={true}
первый <input />
на странице, чтобы, когда компонент монтировался, он получал фокус.
Сосредоточить первый элемент ввода с ошибкой
Это заняло больше времени и было более запутанным. Я храню код, который не имеет отношения к решению для краткости.
Redux Store / Государство
Мне нужно глобальное состояние, чтобы знать, должен ли я установить фокус и отключить его, когда он был установлен, поэтому я не буду переустанавливать фокус при повторной визуализации компонентов (я буду использовать componentDidUpdate()
для проверки установки фокуса. )
Это может быть разработано так, как вы считаете подходящим для вашего приложения.
{
form: {
resetFocus: false,
}
}
Контейнер Компонент
Компонент должен иметь установленное resetfocus
свойство и callBack, чтобы очистить свойство, если оно в конечном итоге устанавливает фокус на себя.
Также обратите внимание, что я организовал своих создателей Action в отдельные файлы, в основном из-за того, что мой проект довольно большой, и я хотел разбить их на более управляемые куски.
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()
метода.
Ура!