Tôi mới gặp phải vấn đề này và tôi đang sử dụng phản ứng 15.0.1 15.0.2 và tôi đang sử dụng cú pháp ES6 và không nhận được những gì tôi cần từ các câu trả lời khác kể từ v.15 đã bỏ cách đây vài tuần và một số this.refs
thuộc tính đã bị phản đối và loại bỏ .
Nói chung, điều tôi cần là:
- Tập trung phần tử đầu vào (trường) đầu tiên khi thành phần gắn kết
- Tập trung phần tử đầu vào (trường) đầu tiên có lỗi (sau khi gửi)
Tôi đang sử dụng:
- React Container / Thành phần trình bày
- Redux
- Bộ định tuyến phản ứng
Tập trung vào yếu tố đầu vào đầu tiên
Tôi đã sử dụng autoFocus={true}
đầu tiên<input />
trên trang để khi thành phần gắn kết, nó sẽ lấy nét.
Tập trung phần tử đầu vào đầu tiên có lỗi
Điều này mất nhiều thời gian hơn và phức tạp hơn. Tôi đang giữ mã không liên quan đến giải pháp cho ngắn gọn.
Cửa hàng Redux / Bang
Tôi cần một trạng thái toàn cầu để biết liệu tôi có nên đặt tiêu điểm và tắt nó khi nó được đặt hay không, vì vậy tôi không tiếp tục đặt lại tiêu điểm khi các thành phần kết xuất lại (Tôi sẽ sử dụng componentDidUpdate()
để kiểm tra lấy nét. )
Điều này có thể được thiết kế khi bạn thấy phù hợp với ứng dụng của bạn.
{
form: {
resetFocus: false,
}
}
Thành phần container
Thành phần sẽ cần phải có thuộc resetfocus
tính được thiết lập và một cuộc gọi lại để xóa thuộc tính nếu kết thúc việc thiết lập tập trung vào chính nó.
Cũng lưu ý, tôi đã sắp xếp Trình tạo hành động của mình thành các tệp riêng biệt do dự án của tôi khá lớn và tôi muốn chia chúng thành nhiều phần dễ quản lý hơn.
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);
Thành phần trình bày
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
}
Tổng quat
Ý tưởng chung là mỗi trường biểu mẫu có thể có lỗi và được tập trung cần tự kiểm tra và nếu nó cần đặt trọng tâm vào chính nó.
Có logic nghiệp vụ cần phải xảy ra để xác định xem trường đã cho có phải là trường phù hợp để đặt tiêu điểm hay không. Điều này không được hiển thị bởi vì nó sẽ phụ thuộc vào từng ứng dụng.
Khi một biểu mẫu được gửi, sự kiện đó cần đặt cờ tiêu điểm toàn cầu resetFocus
thành đúng. Sau đó, khi mỗi thành phần tự cập nhật, nó sẽ thấy rằng nó sẽ kiểm tra xem liệu nó có được lấy nét hay không và nếu có, hãy gửi sự kiện để đặt lại tiêu điểm để các thành phần khác không phải tiếp tục kiểm tra.
chỉnh sửa
Như một lưu ý phụ, tôi đã có logic nghiệp vụ của mình trong tệp "tiện ích" và tôi chỉ xuất phương thức và gọi nó trong mỗi tệpshouldfocus()
phương thức.
Chúc mừng!