Ho appena incontrato questo problema e sto usando reagire 15.0.1 15.0.2 e sto usando la sintassi ES6 e non riusciva a ottenere quello che mi serviva dalle altre risposte dal V.15 sceso settimane fa e alcune delle this.refs
proprietà sono stati deprecati e rimossi .
In generale, ciò di cui avevo bisogno era:
- Mettere a fuoco il primo elemento di input (campo) quando il componente viene montato
- Mettere a fuoco il primo elemento di input (campo) con un errore (dopo l'invio)
Sto usando:
- Contenitore React / Componente presentazione
- Redux
- React-Router
Mettere a fuoco il primo elemento di input
Ho usato autoFocus={true}
il primo<input />
sulla pagina in modo che quando il componente si monta, si focalizzerà.
Mettere a fuoco il primo elemento di input con un errore
Ciò ha richiesto più tempo ed è stato più contorto. Sto tenendo fuori il codice che non è rilevante per la soluzione per brevità.
Negozio / Stato Redux
Ho bisogno di uno stato globale per sapere se devo impostare lo stato attivo e disabilitarlo quando è stato impostato, quindi non continuerò a reimpostare lo stato attivo quando i componenti vengono nuovamente sottoposti componentDidUpdate()
a rendering (userò per verificare l'impostazione dello stato attivo. )
Questo potrebbe essere progettato come ritieni adatto alla tua applicazione.
{
form: {
resetFocus: false,
}
}
Componente contenitore
Il componente dovrà avere la resetfocus
proprietà impostata e un callBack per cancellare la proprietà se finisce per focalizzarsi su se stesso.
Inoltre, ho organizzato i miei creatori di azioni in file separati, principalmente perché il mio progetto è abbastanza grande e volevo suddividerli in blocchi più gestibili.
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 di presentazione
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
}
Panoramica
L'idea generale è che ogni campo del modulo che potrebbe avere un errore ed essere focalizzato deve controllare se stesso e se deve focalizzarsi su se stesso.
C'è una logica aziendale che deve accadere per determinare se il campo dato è il campo giusto su cui focalizzare l'attenzione. Questo non viene visualizzato perché dipenderà dalla singola applicazione.
Quando viene inviato un modulo, quell'evento deve impostare il flag di focus globale resetFocus
su true. Quindi, man mano che ogni componente si aggiorna, vedrà che dovrebbe verificare se ottiene lo stato attivo e, in caso affermativo, invia l'evento per ripristinare lo stato attivo in modo che altri elementi non debbano continuare a controllare.
modifica
Come nota a margine, avevo la mia logica di business in un file "utility" e ho appena esportato il metodo e l'ho chiamato all'interno di ognishouldfocus()
metodo.
Saluti!