Acabo de encontrarme con este problema y estoy usando react 15.0.1 15.0.2 y estoy usando la sintaxis ES6 y no obtuve lo que necesitaba de las otras respuestas ya que v.15 cayó hace algunas semanas y algunas de las this.refs
propiedades fueron desaprobados y eliminados .
En general, lo que necesitaba era:
- Enfoca el primer elemento de entrada (campo) cuando se monta el componente
- Enfoque el primer elemento de entrada (campo) con un error (después de enviar)
Estoy usando:
- Contenedor de reacción / Componente de presentación
- Redux
- React-Router
Enfoca el primer elemento de entrada
Solía autoFocus={true}
en el primero<input />
en la página para que cuando se monte el componente, se enfoque.
Enfoque el primer elemento de entrada con un error
Esto tomó más tiempo y fue más complicado. Estoy manteniendo fuera el código que no es relevante para la solución por brevedad.
Tienda Redux / Estado
Necesito un estado global para saber si debo establecer el enfoque y deshabilitarlo cuando se configuró, por lo que no vuelvo a configurar el enfoque cuando los componentes se vuelven a procesar (lo usaré componentDidUpdate()
para verificar la configuración del enfoque. )
Esto podría diseñarse como mejor le parezca para su aplicación.
{
form: {
resetFocus: false,
}
}
Componente contenedor
El componente necesitará tener la resetfocus
propiedad establecida y un callBack para borrar la propiedad si termina estableciendo el foco en sí mismo.
También tenga en cuenta que organicé mis Action Creators en archivos separados principalmente debido a que mi proyecto es bastante grande y quería dividirlos en trozos más manejables.
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);
Componente de presentación
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
}
Visión general
La idea general es que cada campo de formulario que podría tener un error y estar enfocado necesita verificarse a sí mismo y si necesita establecer el foco en sí mismo.
Hay una lógica de negocios que debe suceder para determinar si el campo dado es el campo correcto para establecer el foco. Esto no se muestra porque dependerá de la aplicación individual.
Cuando se envía un formulario, ese evento debe establecer el indicador de enfoque global resetFocus
en verdadero. Luego, a medida que cada componente se actualice, verá que debe verificar para ver si obtiene el foco y, si lo hace, enviar el evento para restablecer el foco para que otros elementos no tengan que seguir revisando.
editar
Como nota al margen, tenía mi lógica de negocios en un archivo de "utilidades" y simplemente exporté el método y lo llamé dentro de cadashouldfocus()
método.
¡Salud!