दिलचस्प पोस्ट
JQgrid चेकबॉक्स ऑनक्लिक अपडेट डेटाबेस Xcode आईओएस 8 कीबोर्ड प्रकार समर्थित नहीं है एक MDF फ़ाइल क्या है? LINQ के बारे में सीखना स्थानीय स्तर की उपलब्धता उपलब्ध है या नहीं मौजूदा कॉलम के लिए एक डिफ़ॉल्ट मान कैसे सेट करें ArrayAdapter <myClass> का उपयोग कैसे करें उद्देश्य- c / कोको स्पर्श में एक मॉड्यूलो ऑपरेशन कैसे करें? जावा में "अपरिवर्तनीय बयान" कंपाइलर त्रुटि क्यों है? मोबाइल डिवाइस पर बूटस्ट्रैप 3 – डेस्कटॉप दृश्य कैसे जावास्क्रिप्ट के साथ एक क्लिक अनुकरण? अनुक्रमिक गिनती जेनरेटर मैं रनटाइम पर एक चर का प्रकार प्राप्त करना चाहता हूं VARCHAR से INT – MySQL को कास्ट करें जावा क्लास के लिए उपयोग किए जाने वाले चर को किस प्रकार उपयोग किया जाता है?

मैं कैसे Redux में एक मोडल संवाद प्रदर्शित कर सकता हूं जो अतुल्यकालिक कार्य करता है?

मैं एक ऐसे एप का निर्माण कर रहा हूं जिसके लिए कुछ स्थितियों में एक पुष्टि संवाद दिखाने की जरूरत है

मान लीजिए कि मैं कुछ निकालना चाहता हूं, तो मैं deleteSomething(id) तरह एक क्रिया प्रेषित deleteSomething(id) ताकि कुछ प्रसारणकर्ता उस घटना को पकड़ेगा और संवाद दिखाने के लिए इसे दिखाने के लिए भर जाएगा।

मेरा संदेह तब आता है जब यह संवाद प्रस्तुत करता है

  • यह घटक पहले कार्रवाई के अनुसार उचित कार्रवाई कैसे प्रेषित कर सकता है?
  • क्या कार्रवाई निर्माता इस तर्क को संभालना चाहिए?
  • क्या हम reducer के अंदर कार्रवाई जोड़ सकते हैं?

संपादित करें:

इसे स्पष्ट करने के लिए:

 deleteThingA(id) => show dialog with Questions => deleteThingARemotely(id) createThingB(id) => Show dialog with Questions => createThingBRemotely(id) 

इसलिए मैं संवाद घटक पुन: उपयोग करने की कोशिश कर रहा हूं संवाद को दिखाना / छिपा रहा है यह समस्या नहीं है क्योंकि यह आसानी से reducer में किया जा सकता है मैं जो निर्दिष्ट करने का प्रयास कर रहा हूं वह है कि बाईं तरफ के प्रवाह को शुरू करने वाली कार्रवाई के अनुसार सही पक्ष से कार्रवाई कैसे प्रेषित करें

वेब के समाधान से एकत्रित समाधान "मैं कैसे Redux में एक मोडल संवाद प्रदर्शित कर सकता हूं जो अतुल्यकालिक कार्य करता है?"

मेरा सुझाव है कि यह एक बिट वर्बोस है, लेकिन मुझे जटिल ऐप्स में बहुत अच्छी तरह से स्केल किया गया। जब आप एक मॉडल दिखाना चाहते हैं, तो उस क्रिया का आग लगाना जिसे आप देखना चाहते हैं:

मॉडल को दिखाने के लिए एक क्रिया को प्रेषित करना

 this.props.dispatch({ type: 'SHOW_MODAL', modalType: 'DELETE_POST', modalProps: { postId: 42 } }) 

(स्ट्रिंग निश्चित रूप से स्थिर हो सकते हैं; मैं सादगी के लिए इनलाइन स्ट्रिंग का उपयोग कर रहा हूं।)

मॉडल राज्य को प्रबंधित करने के लिए एक रेड्यूसर लिखना

फिर सुनिश्चित करें कि आपके पास एक प्रसारणकर्ता है जो इन मानों को स्वीकार करता है:

 const initialState = { modalType: null, modalProps: {} } function modal(state = initialState, action) { switch (action.type) { case 'SHOW_MODAL': return { modalType: action.modalType, modalProps: action.modalProps } case 'HIDE_MODAL': return initialState default: return state } } /* .... */ const rootReducer = combineReducers({ modal, /* other reducers */ }) 

महान! अब, जब आप कोई क्रिया प्रेषित करते हैं, तो state.modal । वर्तमान में दृश्यमान मोडल विंडो के बारे में जानकारी शामिल करने के लिए state.modal अपडेट होगा।

रूट मॉडल घटक लेखन

अपने घटक पदानुक्रम की जड़ में, एक <ModalRoot> घटक जोड़ें जो कि <ModalRoot> स्टोर से जुड़ा है। यह राज्य को सुनता है। state.modal और राज्य के एक आदर्श मॉडल घटक को प्रदर्शित state.modal.modalProps

 // These are regular React components we will write soon import DeletePostModal from './DeletePostModal' import ConfirmLogoutModal from './ConfirmLogoutModal' const MODAL_COMPONENTS = { 'DELETE_POST': DeletePostModal, 'CONFIRM_LOGOUT': ConfirmLogoutModal, /* other modals */ } const ModalRoot = ({ modalType, modalProps }) => { if (!modalType) { return <span /> // after React v15 you can return null here } const SpecificModal = MODAL_COMPONENTS[modalType] return <SpecificModal {...modalProps} /> } export default connect( state => state.modal )(ModalRoot) 

हमने यहाँ क्या किया है? ModalRoot वर्तमान modalType और modalProps को modalProps से state.modal है, जिस पर यह जुड़ा हुआ है, और संबंधित घटक जैसे कि DeletePostModal या ConfirmLogoutModal । हर मॉडल एक घटक है!

विशिष्ट मॉडल अवयव लिखना

यहां कोई सामान्य नियम नहीं है। वे सिर्फ उन घटकों को दर्शाते हैं जो क्रियाओं को प्रेषित कर सकते हैं, स्टोर राज्य से कुछ पढ़ सकते हैं, और बस मोडल हो सकते हैं

उदाहरण के लिए, DeletePostModal इस तरह DeletePostModal सकता है:

 import { deletePost, hideModal } from '../actions' const DeletePostModal = ({ post, dispatch }) => ( <div> <p>Delete post {post.name}?</p> <button onClick={() => { dispatch(deletePost(post.id)).then(() => { dispatch(hideModal()) }) }}> Yes </button> <button onClick={() => dispatch(hideModal())}> Nope </button> </div> ) export default connect( (state, ownProps) => ({ post: state.postsById[ownProps.postId] }) )(DeletePostModal) 

DeletePostModal स्टोर से जुड़ा हुआ है ताकि वह पोस्ट का शीर्षक प्रदर्शित कर सके और किसी भी कनेक्टेड घटक की तरह काम कर सके: यह छिपाने वाले कार्यों सहित कार्यों को प्रेषित कर सकता है, जब स्वयं छिपाने के लिए आवश्यक हो।

एक प्रस्तुतीकरण घटक को निकालना

प्रत्येक "विशिष्ट" मॉडल के लिए समान लेआउट तर्क को कॉपी-पेस्ट करने के लिए अजीब होगा। लेकिन आपके पास घटकों, सही है? तो आप एक presentational <Modal> घटक को निकाल सकते हैं जो कि विशेष रूप से क्या काम करता है, लेकिन यह पता नहीं चलता कि वह कैसा दिखता है।

उसके बाद, विशिष्ट DeletePostModal जैसे कि DeletePostModal इसे रेंडर करने के लिए उपयोग कर सकते हैं:

 import { deletePost, hideModal } from '../actions' import Modal from './Modal' const DeletePostModal = ({ post, dispatch }) => ( <Modal dangerText={`Delete post ${post.name}?`} onDangerClick={() => dispatch(deletePost(post.id)).then(() => { dispatch(hideModal()) }) }) /> ) export default connect( (state, ownProps) => ({ post: state.postsById[ownProps.postId] }) )(DeletePostModal) 

यह आप पर निर्भर है कि आपके <Modal> आपके आवेदन में स्वीकार कर सकते हैं लेकिन मैं सोचता हूं कि आपके पास कई तरह के मोडल (उदाहरण के लिए जानकारी मोडल, पुष्टिकरण मोडल, आदि) और उनके लिए कई शैलियों ।

क्लिक या बाहरी कुंजी पर एस्केपबिलिटी और छुपिंग

मोडल्स के बारे में अंतिम महत्वपूर्ण हिस्सा यह है कि आम तौर पर हम उन्हें छिपाना चाहते हैं जब उपयोगकर्ता बाहर क्लिक करता है या एस्केप दबाता है।

इसे लागू करने के बारे में सलाह देने के बजाय, मेरा सुझाव है कि आप इसे खुद ही लागू नहीं करें पहुंच योग्यता पर विचार करना कठिन है

इसके बजाय, मैं आपको एक सुलभ ऑफ-द-शेल्फ मोडल घटक जैसे कि react-modal का उपयोग करने का सुझाव देता हूं। यह पूरी तरह से अनुकूलन योग्य है, आप इसे अंदर की कोई भी चीज डाल सकते हैं, लेकिन यह पहुंच को सही तरीके से प्रबंधित करता है ताकि अंधा लोग अभी भी आपके मॉडल का उपयोग कर सकें।

आप अपने खुद के react-modal में react-modal को भी लपेट कर सकते हैं, जो आपके अनुप्रयोगों के लिए विशिष्ट प्रोपोज़र स्वीकार करता है और बाल बटन या अन्य सामग्री उत्पन्न करता है यह सब सिर्फ घटकों है!

अन्य दृष्टिकोण

ऐसा करने का एक से अधिक तरीका है

कुछ लोगों को इस दृष्टिकोण की अभिव्यक्ति पसंद नहीं है और वे एक <Modal> घटक को पसंद करते हैं, जिसे वे "पोर्टल" नामक एक तकनीक के साथ अपने घटकों के अंदर प्रस्तुत कर सकते हैं। पोर्टल आपको अपने अंदर एक घटक प्रदान करते हैं, जबकि वास्तव में यह डीओएम में पूर्व निर्धारित स्थान पर रेंडर करेगा, जो मोडलों के लिए बहुत सुविधाजनक है

वास्तव में पहले से जुड़े हुए react-modal यह आंतरिक रूप से इतनी तकनीकी रूप से आपको शीर्ष पर से रेंडर करने की ज़रूरत नहीं है। मुझे अभी भी यह दिखा रहा है कि मैं इसे दिखा रहा हूँ घटक से दिखाना अच्छा है, लेकिन आप अपने घटकों से सीधे react-modal उपयोग कर सकते हैं, और जो मैंने ऊपर लिखा था उनमें से अधिकांश को छोड़ सकते हैं।

मैं आपको दोनों तरीकों पर विचार करने के लिए प्रोत्साहित करता हूं, उनके साथ प्रयोग करता हूं, और चुन लेता है कि आपके ऐप के लिए और आपकी टीम के लिए सबसे अच्छा क्या काम करता है।

पोर्टल्स का उपयोग करें

दान एब्रामोव का पहला हिस्सा ठीक है, लेकिन इसमें कई बॉयलरप्लेट शामिल हैं जैसा कि उसने कहा था, आप पोर्टल्स का उपयोग भी कर सकते हैं। मैं उस विचार पर थोड़ा विस्तार करूंगा

एक पोर्टल का लाभ यह है कि पॉपअप और बटन रिटक्ट ट्री में बहुत करीब रहता है, बहुत सरल अभिभावक / बाल संचार प्रोप्स का उपयोग करते हुए: आप पोर्टल के साथ आसानी से एसिंक कार्यों को नियंत्रित कर सकते हैं, या माता-पिता पोर्टल को अनुकूलित कर सकते हैं।

एक पोर्टल क्या है?

एक पोर्टल आपको सीधे document.body अंदर प्रस्तुत करने की अनुमति देता है। एक तत्व जो आपके रिटक्ट ट्री में गहराई से नेस्टेड है।

विचार यह है कि उदाहरण के लिए आप शरीर को निम्न रीति-रोटी में प्रस्तुत करते हैं:

 <div className="layout"> <div className="outside-portal"> <Portal> <div className="inside-portal"> PortalContent </div> </Portal> </div> </div> 

और आपको आउटपुट मिलता है:

 <body> <div class="layout"> <div class="outside-portal"> </div> </div> <div class="inside-portal"> PortalContent </div> </body> 

inside-portal नोड को <body> अंदर, सामान्य, गहराई से स्थान के बजाय अनुवादित किया गया है।

पोर्टल का उपयोग कब करना

एक पोर्टल तत्वों को प्रदर्शित करने के लिए विशेष रूप से उपयोगी है जो कि आपके मौजूदा प्रतिक्रिया घटकों के ऊपर जाना चाहिए: पॉपअप, ड्रॉपडाउन, सुझाव, हॉटस्पॉट

पोर्टल का उपयोग क्यों करें

कोई Z- इंडेक्स समस्या अब नहीं : एक पोर्टल आपको <body> को रेंडर करने की अनुमति देती है यदि आप पॉपअप या ड्रॉपडाउन प्रदर्शित करना चाहते हैं, तो यह वास्तव में बहुत अच्छा विचार है यदि आप ज़ी-इंडेक्स समस्याओं से लड़ना नहीं चाहते हैं। पोर्टल तत्वों को जोड़ते हैं। माउंट ऑर्डर में document.body । जिसका अर्थ है कि जब तक आप z-index साथ नहीं खेलते हैं, तो डिफ़ॉल्ट व्यवहार आरोही क्रम में एक दूसरे के ऊपर पोर्टल्स स्टैक करने के लिए होगा। व्यवहार में, इसका मतलब है कि आप एक पॉपअप के अंदर से सुरक्षित रूप से एक पॉपअप खोल सकते हैं, और यह सुनिश्चित कर लें कि दूसरे पॉपअप को पहले के शीर्ष पर प्रदर्शित किया जाएगा, बिना भी z-index बारे में सोचें।

प्रयोग में

सबसे सरल: स्थानीय प्रतिक्रिया का प्रयोग करें: यदि आपको लगता है कि, एक साधारण हटाने के पुष्टिकरण पॉपअप के लिए, यह रेडux बॉयलरप्लेट के लायक नहीं है, तो आप एक पोर्टल का उपयोग कर सकते हैं और यह आपके कोड को सरल बनाता है। ऐसे उपयोग के लिए, जहां बातचीत बहुत स्थानीय है और वास्तव में एक कार्यान्वयन विवरण है, क्या आप वाकई हॉट-रीलोडिंग, टाइम-ट्रैफ़िक, एक्शन लॉगिंग और रेडयुक्स के सभी फायदे लाते हैं? निजी तौर पर मैं इस मामले में स्थानीय राज्य का इस्तेमाल नहीं करता हूं। कोड उतना सरल हो जाता है:

 class DeleteButton extends React.Component { static propTypes = { onDelete: PropTypes.func.isRequired, }; state = { confirmationPopup: false }; open = () => { this.setState({ confirmationPopup: true }); }; close = () => { this.setState({ confirmationPopup: false }); }; render() { return ( <div className="delete-button"> <div onClick={() => this.open()}>Delete</div> {this.state.confirmationPopup && ( <Portal> <DeleteConfirmationPopup onCancel={() => this.close()} onConfirm={() => { this.close(); this.props.onDelete(); }} /> </Portal> )} </div> ); } } 

सरल: आप अभी भी Redux स्थिति का उपयोग कर सकते हैं : यदि आप वास्तव में चाहते हैं, तो आप अभी भी यह चुनने के लिए connect का उपयोग कर सकते हैं कि DeleteConfirmationPopup दिखाया गया है या नहीं। जैसा कि पोर्टल आपके रिटक्ट ट्री में गहराई से बसा हुआ है, यह पोर्टल के व्यवहार को कस्टमाइज़ करने के लिए बहुत सरल है क्योंकि आपके माता-पिता पोर्टल के लिए प्रोप पास कर सकते हैं। यदि आप पोर्टलों का उपयोग नहीं करते हैं, तो आपको आमतौर पर अपने पटकथा को z-index कारणों के लिए रीट पेड़ के शीर्ष पर रेंडर करना पड़ता है, और आमतौर पर इस बारे में सोचना होगा कि "मैं उपयोग के अनुसार जेनरिक DeleteConfirmationPopup को कैसे अनुकूलित करूँ? मामला"। और आम तौर पर आपको इस समस्या का काफी हुक समाधान मिलेगा, जैसे नेस्टेड पुष्टि / रद्द करने वाली क्रियाएं, एक अनुवाद बंडल कुंजी, या उससे भी बदतर, एक रेंडर फ़ंक्शन (या कुछ और अनसुलझी) शामिल हैं। आपको पोर्टल के साथ ऐसा करने की ज़रूरत नहीं है, और केवल नियमित DeleteButton पार कर सकते हैं, चूंकि DeleteConfirmationPopup केवल DeleteButton का एक बच्चा है

निष्कर्ष

पोर्टल आपके कोड को आसान बनाने के लिए बहुत उपयोगी हैं I मैं उनके बिना अब और नहीं कर सकता था।

ध्यान दें कि पोर्टल लागू करने से आपको अन्य उपयोगी विशेषताओं के साथ भी मदद मिल सकती है जैसे:

  • सरल उपयोग
  • पोर्टल को बंद करने के लिए एस्प्रेस शॉर्टकट
  • बाहरी क्लिक करें (बंद पोर्टल या नहीं)
  • संभाल लिंक क्लिक करें (बंद पोर्टल या नहीं)
  • संदर्भ प्रस्तुति पोर्टल पेड़ में उपलब्ध है

प्रतिक्रिया-पोर्टल या प्रतिक्रिया-मोडल पॉप – अप, मोडल और ओवरले के लिए अच्छा है, जो कि पूर्ण-स्क्रीन होना चाहिए, आमतौर पर स्क्रीन के बीच में केंद्रित होता है।

रिएक्ट-टेदर सबसे डेवलपर्स पर प्रतिक्रिया के द्वारा अज्ञात है, फिर भी यह सबसे उपयोगी टूल में से एक है जिसे आप वहां ढूंढ सकते हैं। टिथर आपको पोर्टल बनाने के लिए अनुमति देता है, लेकिन स्वचालित रूप से किसी दिए गए लक्ष्य के सापेक्ष पोर्टल की स्थिति में होगा। टूलटिप्स, ड्रॉपडाउन, हॉटस्पॉट्स, हेल्पबॉक्सेस … के लिए यह एकदम सही है … यदि आपको स्थिति absolute / relative और z-index , या आपके व्यूपोर्ट से बाहर जाने वाले आपके ड्रॉपडाउन के साथ कोई समस्या हो गई है, तो टिथर आपके लिए वह सभी का समाधान करेगा

उदाहरण के लिए, आप हॉटस्पॉट्स को आसानी से लागू कर सकते हैं, जो एक बार क्लिक किए गए टूलटिप में विस्तार होता है:

हॉटस्पॉट ऑनबोर्डिंग

असली उत्पादन कोड यहाँ। कोई आसान नहीं हो सकता 🙂

 <MenuHotspots.contacts> <ContactButton/> </MenuHotspots.contacts> 

संपादित करें : बस रिएक्शन-गेटवे की खोज की गई है जो पोर्टल्स को अपनी पसंद के नोड में प्रस्तुत करने की अनुमति देती है (जरूरी नहीं कि शरीर)

संपादित करें : ऐसा प्रतीत होता है कि प्रतिक्रिया-पॉपर प्रतिक्रिया-पलटने के लिए एक सभ्य विकल्प हो सकता है। पॉपरजेएस एक ऐसी चीज है जो केवल एक तत्व के लिए उपयुक्त स्थिति की गणना करता है, सीधे डोम को छूने के बिना, उपयोगकर्ता को यह चुनने देता है कि जब वह डोम नोड डालना चाहता है, जबकि टिथर शरीर को सीधे जोड़ता है

संपादित करें : प्रतिक्रिया के अगले संस्करण (फाइबर: शायद 16 या 17) में पोर्टल्स बनाने की एक विधि शामिल होगी: ReactDOM.unstable_createPortal() लिंक

विषय पर जे एस समुदाय के ज्ञात विशेषज्ञों द्वारा बहुत अच्छे समाधान और मूल्यवान टिप्पणियां यहां पाई जा सकती हैं। यह एक संकेतक हो सकता है कि यह छोटी छोटी समस्या नहीं है जैसा कि ऐसा लग सकता है मुझे लगता है कि यही कारण है कि इस मुद्दे पर संदेह और अनिश्चितता का स्रोत हो सकता है।

यहां मूलभूत समस्या यह है कि प्रतिक्रिया में आपको केवल अपने माता पिता को घटक माउंट करने की अनुमति दी जाती है, जो वांछित व्यवहार हमेशा नहीं होता है लेकिन इस मुद्दे को कैसे संबोधित किया जाए?

मैं समाधान का प्रस्ताव, इस मुद्दे को ठीक करने के लिए संबोधित किया। अधिक विस्तृत समस्या परिभाषा, स्रोत और उदाहरण यहां मिल सकते हैं: https://github.com/fckt/react-layer-stack#rationale

दलील

react / react-dom 2 बुनियादी मान्यताओं / विचारों के साथ आता है:

  • हर यूआई स्वाभाविक रूप से पदानुक्रमित है यही वजह है कि हमारे पास एक दूसरे के टुकड़े लपेटे जाने वाले components का विचार है
  • react-dom माउंट (शारीरिक रूप से) बच्चे के मूलभूत रूप से अपने मूल डोम नोड में घटक

समस्या यह है कि कभी-कभी दूसरी संपत्ति नहीं है जो आप अपने मामले में चाहते हैं। कभी-कभी आप अपने घटक को विभिन्न भौतिक DOM नोड में माउंट करना चाहते हैं और एक ही समय में माता-पिता और बच्चे के बीच तार्किक संबंध रखना चाहते हैं।

कैनोनिकल उदाहरण टूलटिप-जैसे घटक है: विकास प्रक्रिया के कुछ बिंदु पर आप पाएंगे कि आपको अपने UI element लिए कुछ विवरण जोड़ने की ज़रूरत है: यह निश्चित परत में रेंडर करेगी और इसे इसके निर्देशांक पता होना चाहिए (जो कि UI element समन्वय या माउस हैं कॉओर्ड्स) और साथ ही साथ जानकारी की जरूरत है कि उसे अभी दिखाया जाना चाहिए या नहीं, इसकी सामग्री और मूल घटकों से कुछ संदर्भ। यह उदाहरण दिखाता है कि कभी-कभी तार्किक पदानुक्रम भौतिक DOM पदानुक्रम के साथ मेल नहीं खाता है।

आपके प्रश्न का उत्तर देने वाला ठोस उदाहरण देखने के लिए https://github.com/fckt/react-layer-stack/blob/master/README.md#real-world-usage-example पर एक नज़र डालें:

 import { Layer, LayerContext } from 'react-layer-stack' // ... for each `object` in array of `objects` const modalId = 'DeleteObjectConfirmation' + objects[rowIndex].id return ( <Cell {...props}> // the layer definition. The content will show up in the LayerStackMountPoint when `show(modalId)` be fired in LayerContext <Layer use={[objects[rowIndex], rowIndex]} id={modalId}> {({ hideMe, // alias for `hide(modalId)` index } // useful to know to set zIndex, for example , e) => // access to the arguments (click event data in this example) <Modal onClick={ hideMe } zIndex={(index + 1) * 1000}> <ConfirmationDialog title={ 'Delete' } message={ "You're about to delete to " + '"' + objects[rowIndex].name + '"' } confirmButton={ <Button type="primary">DELETE</Button> } onConfirm={ this.handleDeleteObject.bind(this, objects[rowIndex].name, hideMe) } // hide after confirmation close={ hideMe } /> </Modal> } </Layer> // this is the toggle for Layer with `id === modalId` can be defined everywhere in the components tree <LayerContext id={ modalId }> {({showMe}) => // showMe is alias for `show(modalId)` <div style={styles.iconOverlay} onClick={ (e) => showMe(e) }> // additional arguments can be passed (like event) <Icon type="trash" /> </div> } </LayerContext> </Cell>) // ...