Bài viết Confirming Navigation giải thích cách sử dụng hộp xác nhận trình duyệt trong móc chuyển tiếp của bạn. Khỏe. Nhưng tôi muốn sử dụng hộp thoại của riêng mình. Nếu tôi đã sử dụng các phương pháp từ mô-đun history
tôi nghĩ rằng điều này là có thể. Có thể thực hiện điều này với setRouteLeaveHook
trong bộ phản ứng-bộ định tuyến không?Làm thế nào để sử dụng một thành phần tùy chỉnh với các chuyển đổi tuyến đường phản ứng-bộ định tuyến?
Trả lời
Vấn đề cốt lõi là setRouteLeaveHook
dự kiến hàm móc sẽ trả lại kết quả đồng bộ. Điều này có nghĩa là bạn không có thời gian để hiển thị thành phần hộp thoại tùy chỉnh, hãy đợi người dùng nhấp vào tùy chọn và rồi trả về kết quả. Vì vậy, chúng tôi cần một cách để chỉ định móc không đồng bộ. Dưới đây là một chức năng hữu ích, tôi đã viết:
// Asynchronous version of `setRouteLeaveHook`.
// Instead of synchronously returning a result, the hook is expected to
// return a promise.
function setAsyncRouteLeaveHook(router, route, hook) {
let withinHook = false
let finalResult = undefined
let finalResultSet = false
router.setRouteLeaveHook(route, nextLocation => {
withinHook = true
if (!finalResultSet) {
hook(nextLocation).then(result => {
finalResult = result
finalResultSet = true
if (!withinHook && nextLocation) {
// Re-schedule the navigation
router.push(nextLocation)
}
})
}
let result = finalResultSet ? finalResult : false
withinHook = false
finalResult = undefined
finalResultSet = false
return result
})
}
Dưới đây là một ví dụ về cách sử dụng nó, sử dụng vex để hiển thị một hộp thoại:
componentWillMount() {
setAsyncRouteLeaveHook(this.context.router, this.props.route, this.routerWillLeave)
}
routerWillLeave() {
return new Promise((resolve, reject) => {
if (!this.state.textValue) {
// No unsaved changes -- leave
resolve(true)
} else {
// Unsaved changes -- ask for confirmation
vex.dialog.confirm({
message: 'There are unsaved changes. Leave anyway?' + nextLocation,
callback: result => resolve(result)
})
}
})
}
Cảm ơn Daniel. Bạn có nói rằng nếu setRouteLeaveHook chỉ sử dụng hộp xác nhận trình duyệt mặc định thì điều này được thực hiện đồng bộ không? –
FYI, điều này cũng hoạt động tuyệt vời với hộp thoại thoại/hộp thoại. –
Cảm ơn giải pháp, tôi đã tự hỏi nếu 'router.push (nextLocation)' sẽ luôn hoạt động, không có vấn đề nếu người dùng đang nhấp vào nút quay lại hoặc nút tiến. Có vẻ như 'push' ngụ ý chỉ một hướng, nhưng có lẽ tôi đã nhầm lẫn. – majorBummer
Trên đây là lớn trừ khi người dùng quay trở lại trong lịch sử. Nội dung như sau sẽ khắc phục sự cố:
if (!withinHook && nextLocation) {
if (nextLocation.action=='POP') {
router.goBack()
} else {
router.push(nextLocation)
}
}
Đây là giải pháp của tôi cho tương tự. Tôi đã tạo thành phần hộp thoại tùy chỉnh mà bạn có thể sử dụng để bọc bất kỳ thành phần nào trong ứng dụng của mình. Bạn có thể bọc tiêu đề của bạn và cách này có nó xuất hiện trên tất cả các trang. Giả sử bạn đang sử dụng Biểu mẫu Redux, nhưng bạn có thể chỉ cần thay thế areThereUnsavedChanges
bằng một số mã kiểm tra thay đổi biểu mẫu khác. Nó cũng sử dụng phương thức React Bootstrap, một lần nữa bạn có thể thay thế bằng hộp thoại tùy chỉnh của riêng mình.
import React, { Component } from 'react'
import { connect } from 'react-redux'
import { withRouter, browserHistory } from 'react-router'
import { translate } from 'react-i18next'
import { Button, Modal, Row, Col } from 'react-bootstrap'
// have to use this global var, because setState does things at unpredictable times and dialog gets presented twice
let navConfirmed = false
@withRouter
@connect(
state => ({ form: state.form })
)
export default class UnsavedFormModal extends Component {
constructor(props) {
super(props)
this.areThereUnsavedChanges = this.areThereUnsavedChanges.bind(this)
this.state = ({ unsavedFormDialog: false })
}
areThereUnsavedChanges() {
return this.props.form && Object.values(this.props.form).length > 0 &&
Object.values(this.props.form)
.findIndex(frm => (Object.values(frm)
.findIndex(field => field && field.initial && field.initial !== field.value) !== -1)) !== -1
}
render() {
const moveForward =() => {
this.setState({ unsavedFormDialog: false })
navConfirmed = true
browserHistory.push(this.state.nextLocation.pathname)
}
const onHide =() => this.setState({ unsavedFormDialog: false })
if (this.areThereUnsavedChanges() && this.props.router && this.props.routes && this.props.routes.length > 0) {
this.props.router.setRouteLeaveHook(this.props.routes[this.props.routes.length - 1], (nextLocation) => {
if (navConfirmed || !this.areThereUnsavedChanges()) {
navConfirmed = false
return true
} else {
this.setState({ unsavedFormDialog: true, nextLocation: nextLocation })
return false
}
})
}
return (
<div>
{this.props.children}
<Modal show={this.state.unsavedFormDialog} onHide={onHide} bsSize="sm" aria-labelledby="contained-modal-title-md">
<Modal.Header>
<Modal.Title id="contained-modal-title-md">WARNING: unsaved changes</Modal.Title>
</Modal.Header>
<Modal.Body>
Are you sure you want to leave the page without saving changes to the form?
<Row>
<Col xs={6}><Button block onClick={onHide}>Cancel</Button></Col>
<Col xs={6}><Button block onClick={moveForward}>OK</Button></Col>
</Row>
</Modal.Body>
</Modal>
</div>
)
}
}
Tôi đã làm cho nó hoạt động bằng cách đặt trạng thái boolean cho dù bạn đã xác nhận điều hướng (sử dụng bộ phản ứng 2.8.x). Vì nó nói trong liên kết mà bạn đã đăng: https://github.com/ReactTraining/react-router/blob/master/docs/guides/ConfirmingNavigation.md
trở lại sai để ngăn chặn một sự chuyển tiếp w/o khiến người sử dụng
Tuy nhiên, họ quên đề cập rằng móc nên không đăng ký là tốt, xem here và here.
Chúng ta có thể sử dụng để thực hiện các giải pháp của riêng của chúng tôi như sau:
class YourComponent extends Component {
constructor() {
super();
const {route} = this.props;
const {router} = this.context;
this.onCancel = this.onCancel.bind(this);
this.onConfirm = this.onConfirm.bind(this);
this.unregisterLeaveHook = router.setRouteLeaveHook(
route,
this.routerWillLeave.bind(this)
);
}
componentWillUnmount() {
this.unregisterLeaveHook();
}
routerWillLeave() {
const {hasConfirmed} = this.state;
if (!hasConfirmed) {
this.setState({showConfirmModal: true});
// Cancel route change
return false;
}
// User has confirmed. Navigate away
return true;
}
onCancel() {
this.setState({showConfirmModal: false});
}
onConfirm() {
this.setState({hasConfirmed: true, showConfirmModal: true}, function() {
this.context.router.goBack();
}.bind(this));
}
render() {
const {showConfirmModal} = this.state;
return (
<ConfirmModal
isOpen={showConfirmModal}
onCancel={this.onCancel}
onConfirm={this.onConfirm} />
);
}
}
YourComponent.contextTypes = {
router: routerShape
};
- 1. Sử dụng Html.BeginForm() với các tuyến đường tùy chỉnh
- 2. Làm thế nào để unmount một thành phần về biến đổi tuyến đường
- 3. Giữ các thành phần giữa các tuyến đường bằng cách sử dụng phản ứng-router
- 4. Zend Framework: Cách chuyển hướng các tuyến đường cũ sang tuyến đường tùy chỉnh mới 301 như thế nào?
- 5. phản ứng-bộ định tuyến - tạo các tuyến đường lồng nhau không có thành phần làm tổ
- 6. phản ứng-bộ định tuyến không chờ đợi hoạt ảnh trước khi thay đổi tuyến đường
- 7. Restrict tuyến sử dụng tùy chỉnh khớp
- 8. Thêm tùy chỉnh: các tuyến đường mới sử dụng Rails 3 tuyến
- 9. Làm thế nào để sử dụng middleware tuyến tùy chỉnh với Sails.js? (ExpressJS)
- 10. Làm thế nào để làm cho ASP.NET định tuyến thoát khỏi giá trị tuyến đường?
- 11. Sử dụng định tuyến góc dọc theo tuyến đường tròn
- 12. Làm thế nào để sử dụng ActiveResource với các tuyến đường được làm tổ?
- 13. Có cách nào, ở Django, để xác định các tuyến đường sử dụng cú pháp tuyến đường kiểu Flask không?
- 14. Laravel: Cách phản hồi với lỗi 404 tùy chỉnh tùy thuộc vào tuyến đường
- 15. Có thể thay đổi thứ tự các tuyến trong bảng định tuyến khi sử dụng định tuyến thuộc tính không?
- 16. Tùy chỉnh định tuyến ASP.NET Web Api
- 17. Bộ định tuyến phản ứng - Các tuyến đường lồng nhau không hoạt động
- 18. Định tuyến i18n tùy chỉnh trong Symfony
- 19. Làm thế nào để bỏ qua một tuyến đường cụ thể trong ASP.NET MVC định tuyến
- 20. Sử dụng neo với bộ định tuyến phản ứng
- 21. Làm cách nào để chuyển hướng đến URL bên ngoài từ tuyến đường angular2 mà không sử dụng thành phần?
- 22. Tuyến đường/lối đi/đường tùy chỉnh trên Google Maps
- 23. Tuyến đường mặc định cho đường dẫn gốc sử dụng thuộc tính asp.net định tuyến
- 24. Bộ định tuyến mới góc - Các thành phần và định tuyến lồng nhau
- 25. Xác định bằng tay các tuyến đường sử dụng Flask
- 26. Làm cách nào để phản hồi bộ định tuyến phản hồi với mã trạng thái 404?
- 27. Làm thế nào để tiêm bộ định tuyến thành phần trong Angular 1.5?
- 28. Làm cách nào để định cấu hình các tuyến tùy chỉnh trong Phalcon?
- 29. Làm cách nào để đặt kiểu nội tuyến-cuộn tràn nội tuyến trên thành phần phản ứng
- 30. Làm thế nào để sử dụng rspec để kiểm tra các tuyến đường được đặt tên?
Để hoàn chỉnh: đây là liên kết đó cho thấy làm thế nào để thêm một hộp thoại tùy chỉnh khi sử dụng các mô-đun lịch sử. https://github.com/mjackson/history/blob/master/docs/ConfirmingNavigation.md –