Я щойно зіткнувся з цим питанням, і я використовую синтаксис react 15.0.1 15.0.2, і я використовую синтаксис ES6, і я не зовсім отримав те, що мені потрібно з інших відповідей, оскільки v.15 випав тижнів тому і деякі this.refs
властивості були застарілі та вилучені .
Загалом, мені було потрібно:
- Сфокусуйте перший елемент введення (поля), коли компонент кріпиться
- Сфокусуйте перший елемент (поля) з помилкою (після надсилання)
Я використовую:
- Реактивний контейнер / презентаційний компонент
- Редукс
- React-Router
Сфокусуйте перший елемент введення
Я використовував autoFocus={true}
на першій <input />
сторінці, так що, коли компонент змонтується, він отримає фокус.
Сфокусуйте перший елемент введення за допомогою помилки
Це зайняло більше часу і було більш звивистим. Я зберігаю код, який не стосується рішення для стислості.
Магазин Redux / Штат
Мені потрібен глобальний стан, щоб знати, чи слід встановлювати фокус, і відключати його, коли він був встановлений, тому я не продовжую повторно налаштовувати фокус, коли компоненти повторно рендеруються (я буду використовувати componentDidUpdate()
для перевірки встановлення фокусу. )
Це може бути розроблено так, як ви вважаєте, що підходить для вашої програми.
{
form: {
resetFocus: false,
}
}
Компонент контейнера
Для resetfocus
очищення властивості для компонента потрібно встановити властивість та callBack, якщо він закінчиться, налаштувавши фокус на себе.
Також зауважте, я організував Моїх творців дій в окремі файли, в основному завдяки мій проект досить великий, і я хотів розбити їх на більш керовані шматки.
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()
методі.
Ура!