Je viens de rencontrer ce problème et j'utilise react 15.0.1 15.0.2 et j'utilise la syntaxe ES6 et je n'ai pas tout à fait obtenu ce dont j'avais besoin des autres réponses depuis la version 15 supprimée il y a des semaines et certaines des this.refs
propriétés ont été dépréciés et retirés .
En général, ce dont j'avais besoin était:
- Concentrez le premier élément d'entrée (champ) lorsque le composant est monté
- Concentrez le premier élément d'entrée (champ) avec une erreur (après la soumission)
J'utilise:
- Conteneur React / Composant de présentation
- Redux
- React-Router
Focus sur le premier élément d'entrée
J'ai utilisé autoFocus={true}
le premier<input />
sur la page de sorte que lorsque le composant sera monté, il se concentrera.
Concentrez le premier élément d'entrée avec une erreur
Cela a pris plus de temps et était plus compliqué. Je garde le code qui n'est pas pertinent pour la solution par souci de concision.
Magasin / état Redux
J'ai besoin d'un état global pour savoir si je dois définir le focus et le désactiver quand il a été défini, donc je ne continue pas à redéfinir le focus lorsque les composants sont rendus (je vais utiliser componentDidUpdate()
pour vérifier le réglage du focus. )
Cela pourrait être conçu comme bon vous semble pour votre application.
{
form: {
resetFocus: false,
}
}
Composant de conteneur
Le composant devra avoir le resetfocus
propriété définie et un callBack pour effacer la propriété s'il finit par définir le focus sur lui-même.
Notez également que j'ai organisé mes créateurs d'action dans des fichiers séparés, principalement en raison de mon projet est assez volumineux et je voulais les diviser en morceaux plus gérables.
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);
Composant de présentation
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
}
Aperçu
L'idée générale est que chaque champ de formulaire qui pourrait avoir une erreur et être concentré doit se vérifier lui-même et s'il doit se concentrer sur lui-même.
Il y a une logique métier qui doit se produire pour déterminer si le champ donné est le bon champ pour définir le focus. Cela ne s'affiche pas car cela dépendra de l'application individuelle.
Lorsqu'un formulaire est soumis, cet événement doit définir l'indicateur de focus global resetFocus
sur true. Puis, au fur et à mesure que chaque composant se met à jour, il verra qu'il doit vérifier s'il obtient le focus et si c'est le cas, répartir l'événement pour réinitialiser le focus afin que les autres éléments n'aient pas à continuer de vérifier.
edit
En remarque, j'avais ma logique métier dans un fichier "utilitaires" et je viens d'exporter la méthode et de l'appeler dans chaqueshouldfocus()
méthode.
À votre santé!