लेख Confirming Navigation बताता है कि आपके संक्रमण हुक में ब्राउज़र पुष्टिकरण बॉक्स का उपयोग कैसे करें। ठीक। लेकिन मैं अपने खुद के संवाद बॉक्स का उपयोग करना चाहता हूं। अगर मैं history
मॉड्यूल से विधियों का उपयोग करना चाहता था तो मुझे लगता है कि यह संभव है। प्रतिक्रिया-राउटर में setRouteLeaveHook
के साथ ऐसा करना संभव है?प्रतिक्रिया-राउटर मार्ग संक्रमण के साथ एक कस्टम घटक का उपयोग कैसे करें?
उत्तर
मूल समस्या यह है कि setRouteLeaveHook
हुक फ़ंक्शन को इसके परिणाम सिंक्रनाइज़ वापस करने की अपेक्षा करता है। इसका मतलब है कि आपके पास एक कस्टम संवाद घटक प्रदर्शित करने का समय नहीं है, उपयोगकर्ता को एक विकल्प पर क्लिक करने के लिए प्रतीक्षा करें, और फिर परिणाम लौटाएं। इसलिए हमें एसिंक्रोनस हुक निर्दिष्ट करने का एक तरीका चाहिए। यहाँ एक उपयोगिता समारोह मैंने लिखा है:
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)
})
}
})
}
धन्यवाद डैनियल। क्या आप कह रहे हैं कि अगर setRouteLeaveHook केवल डिफ़ॉल्ट ब्राउज़र पुष्टिकरण बॉक्स का उपयोग करता है तो इसे सिंक्रनाइज़ तरीके से निष्पादित किया जाता है? –
एफवाईआई, यह संवाद/संवाद पॉलीफिल के साथ भी बहुत अच्छा काम करता है। –
समाधान के लिए धन्यवाद, मैं सोच रहा था कि 'router.push (nextLocation)' हमेशा काम करेगा, भले ही उपयोगकर्ता बैक या फॉरवर्ड बटन पर क्लिक कर रहा हो। ऐसा लगता है कि 'पुश' का अर्थ केवल एक दिशा है, लेकिन शायद मैं गलत हूं। – majorBummer
से ऊपर को छोड़कर जब उपयोगकर्ता इतिहास में वापस चला जाता है महान है:
// 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
})
}
इसका इस्तेमाल करने के लिए, vex का उपयोग कर एक संवाद बॉक्स प्रदर्शित करने के लिए का एक उदाहरण है। निम्न की तरह कुछ समस्या को ठीक करना चाहिए:
if (!withinHook && nextLocation) {
if (nextLocation.action=='POP') {
router.goBack()
} else {
router.push(nextLocation)
}
}
यहां मेरा समाधान है। मैंने एक कस्टम संवाद घटक बनाया है जिसका उपयोग आप अपने ऐप में किसी भी घटक को लपेटने के लिए कर सकते हैं। आप अपने हेडर को लपेट सकते हैं और इस तरह यह सभी पृष्ठों पर मौजूद है। यह मानता है कि आप रेडक्स फॉर्म का उपयोग कर रहे हैं, लेकिन आप बस कुछ अन्य फॉर्म चेंज चेकिंग कोड के साथ areThereUnsavedChanges
को प्रतिस्थापित कर सकते हैं। यह रिएक्ट बूटस्ट्रैप मोडल का भी उपयोग करता है, जिसे आप फिर से अपने स्वयं के कस्टम संवाद से प्रतिस्थापित कर सकते हैं।
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>
)
}
}
मैं इसे राज्य आप यहां से जाना की पुष्टि की है, इस पर एक बूलियन सेट करके काम बना (प्रतिक्रिया रूटर 2.8.x का उपयोग)। यह लिंक में कहते हैं आप पोस्ट: https://github.com/ReactTraining/react-router/blob/master/docs/guides/ConfirmingNavigation.md
वापसी झूठी/उपयोगकर्ता
हालांकि, वे भूल जाते हैं कि हुक के साथ-साथ गैर-पंजीकृत होना चाहिए उल्लेख करने के लिए उत्साह ओ डब्ल्यू एक संक्रमण को रोकने के लिए, here और here देखें।
हम इस प्रकार हमारे अपने समाधान को लागू करने के लिए इसका उपयोग कर सकते हैं:
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. मार्ग संक्रमण के लिए एम्बर एकीकरण परीक्षण कैसे करें?
- 2. नॉकआउट घटक में कस्टम तत्व का उपयोग कैसे करें?
- 3. एक कस्टम वाईआई घटक
- 4. कोणीय 2 के साथ एक एपीआई का उपयोग कैसे करें?
- 5. वू: घटक के साथ स्टोर का उपयोग कैसे करें?
- 6. एक कस्टम घुमाओ घटक
- 7. मार्ग परिवर्तन पर एक घटक अनमाउंट करने के लिए कैसे
- 8. एम्बर संक्रमण आसानी से भेजने के बिना एक घटक में प्रवेश करें
- 9. उपयोग कस्टम घटक इनपुट प्रकार
- 10. UIViewControllerAnimatedTransitioning का उपयोग कैसे करें UINavigationController के साथ?
- 11. मार्ग संक्रमण के बीच रपट AngularJS
- 12. विभिन्न मार्ग समान घटक
- 13. कोणीय यूआई $ मोडल घटक संक्रमण
- 14. संबंधित वस्तुओं के साथ कस्टम मैनेजर का उपयोग कैसे करें?
- 15. मार्ग के साथ एक कस्टम Google मानचित्र मार्कर को एनिमेट कैसे करें?
- 16. popViewControllerAnimated: कस्टम संक्रमण एनीमेशन?
- 17. मैवेन के साथ मेरे कस्टम आर्केटाइप का उपयोग कैसे करें?
- 18. मैपकिट फ्रेमवर्क के साथ कस्टम आइकन का उपयोग कैसे करें?
- 19. रिएक्ट रेडक्स कनेक्ट घटक के साथ एचओसी का उपयोग करें
- 20. पर्सफोर्स के साथ कस्टम तुलना टूल का उपयोग कैसे करें?
- 21. कस्टम प्रकारों के साथ unordered_set का उपयोग कैसे करें?
- 22. कस्टम अनुभाग के साथ ConfigurationManager.AppSettings का उपयोग कैसे करें?
- 23. प्रतिक्रिया घटक के साथ event.target का उपयोग
- 24. एक समग्र घटक के अंदर एक इनपुट घटक के लिए एक वैधकर्ता कैसे निर्दिष्ट करें?
- 25. एक प्रतिक्रिया/प्रवाह घटक में राज्य संक्रमण को कैसे संभालें
- 26. संक्रमण का उपयोग कर संक्रमण व्यवहार FromView और संक्रमण WithView
- 27. प्रतिक्रिया-राउटर - कोई घटक घोंसले के साथ नेस्टेड मार्ग बनाना
- 28. आईओएस 7 कस्टम इंटरैक्टिव संक्रमण का उपयोग केवल कुछ समय
- 29. WinRT XAML कस्टम संक्रमण
- 30. एक ही घटक के लिए कोणीय 2 मार्ग
पूर्णता के लिए: इस लिंक जब इतिहास मॉड्यूल का उपयोग कर एक कस्टम संवाद बॉक्स जोड़ने का तरीका बताता है। https://github.com/mjackson/history/blob/master/docs/ConfirmingNavigation.md –