Właśnie natknąłem się na ten problem i używam reagowania 15.0.1 15.0.2 i używam składni ES6 i nie otrzymałem tego, czego potrzebowałem od innych odpowiedzi, odkąd wer. 15 spadło kilka tygodni temu i niektórych this.refs
właściwości były przestarzałe i usunięte .
Ogólnie potrzebowałem:
- Skoncentruj pierwszy element wejściowy (pole) podczas montowania komponentu
- Ustaw pierwszy element wejściowy (pole) z błędem (po przesłaniu)
Używam:
- Reaguj pojemnik / element prezentacji
- Redux
- React-Router
Skoncentruj pierwszy element wejściowy
Użyłem autoFocus={true}
pierwszego <input />
na stronie, aby po zamontowaniu komponent uzyskał ostrość.
Skoncentruj pierwszy element wejściowy na błędzie
Trwało to dłużej i było bardziej skomplikowane. Trzymam kod, który nie jest odpowiedni dla rozwiązania dla zwięzłości.
Redux Store / State
Potrzebuję stanu globalnego, aby wiedzieć, czy powinienem ustawić fokus i wyłączyć go, gdy był ustawiony, więc nie ustawiam ponownie fokusu podczas ponownego renderowania komponentów (użyję componentDidUpdate()
do sprawdzenia ustawienia fokusa). )
Można to zaprojektować według własnego uznania.
{
form: {
resetFocus: false,
}
}
Komponent kontenerowy
Komponent będzie musiał mieć resetfocus
ustawioną właściwość i callBack, aby wyczyścić właściwość, jeśli zakończy się ustawianie fokusu na sobie.
Pamiętaj też, że zorganizowałem Action Creators w osobne pliki, głównie ze względu na to, że mój projekt jest dość duży i chciałem podzielić je na łatwiejsze do zarządzania części.
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);
Komponent prezentacji
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
}
Przegląd
Ogólna idea jest taka, że każde pole formularza, które może zawierać błąd i być zogniskowane, musi sprawdzić się i czy musi skupić się na sobie.
Istnieje logika biznesowa, która musi się zdarzyć, aby określić, czy dane pole jest właściwym polem, na które należy ustawić fokus. Nie jest to pokazane, ponieważ będzie zależeć od indywidualnej aplikacji.
Po przesłaniu formularza to zdarzenie musi ustawić flagę globalnego fokusa resetFocus
na wartość true. Następnie, gdy każdy komponent aktualizuje się sam, zobaczy, że powinien sprawdzić, czy uzyska fokus, a jeśli tak, wyślij zdarzenie, aby zresetować fokus, aby inne elementy nie musiały sprawdzać dalej.
edytuj
Na marginesie, miałem logikę biznesową w pliku „narzędzi”, po prostu wyeksportowałem metodę i wywołałem ją w każdymshouldfocus()
metody.
Twoje zdrowie!