วิธีที่ฉันแนะนำคือ verbose เล็กน้อย แต่ฉันพบว่ามันทำให้สเกลค่อนข้างดีในแอพที่ซับซ้อน เมื่อคุณต้องการที่จะแสดงคำกริยาไฟดำเนินการอธิบายที่กิริยาช่วยที่คุณต้องการที่จะเห็น:
ส่งการกระทำเพื่อแสดงเป็นกิริยาช่วย
this.props.dispatch({
type: 'SHOW_MODAL',
modalType: 'DELETE_POST',
modalProps: {
postId: 42
}
})
(สตริงอาจเป็นค่าคงที่แน่นอน; ฉันใช้สตริงแบบอินไลน์เพื่อความเรียบง่าย)
เขียน Reducer เพื่อจัดการ Modal State
จากนั้นตรวจสอบให้แน่ใจว่าคุณมีตัวลดที่เพิ่งยอมรับค่าเหล่านี้:
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
จะอัปเดตเพื่อรวมข้อมูลเกี่ยวกับหน้าต่างโมดัลที่มองเห็นได้ในปัจจุบัน
การเขียนคอมโพเนนต์ Modal Root
ที่รากของลำดับชั้นส่วนประกอบของคุณเพิ่ม<ModalRoot>
คอมโพเนนต์ที่เชื่อมต่อกับที่เก็บ Redux มันจะฟัง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
จากstate.modal
ที่มันเชื่อมต่อและแสดงองค์ประกอบที่สอดคล้องกันเช่นDeletePostModal
หรือConfirmLogoutModal
หรือทุกคำกริยาเป็นองค์ประกอบ!
การเขียนส่วนประกอบของคำกริยาเฉพาะ
ไม่มีกฎทั่วไปที่นี่ พวกเขาเป็นเพียงการตอบสนองส่วนประกอบที่สามารถส่งการกระทำอ่านอะไรจากรัฐจัดเก็บและเพิ่งเกิดขึ้นจะเป็นโครงสร้างข้างล่าง
ตัวอย่างเช่น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
มีการเชื่อมต่อไปยังร้านค้าเพื่อที่จะสามารถแสดงชื่อโพสต์และการทำงานเช่นองค์ประกอบที่เชื่อมต่อใด ๆ มันสามารถส่งการกระทำรวมทั้งhideModal
เมื่อมีความจำเป็นต้องซ่อนตัวเอง
แยกส่วนประกอบที่นำเสนอ
มันจะแปลกที่จะคัดลอกวางตรรกะรูปแบบเดียวกันสำหรับทุก "เฉพาะ" modal แต่คุณมีส่วนประกอบใช่มั้ย ดังนั้นคุณสามารถแยกงานนำเสนอได้ <Modal>
ส่วนประกอบที่เกี่ยวที่ไม่ทราบว่าโมดัลพิเศษทำอะไร แต่จัดการกับลักษณะที่ปรากฏ
จากนั้นโมดูลที่เฉพาะเจาะจงเช่น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>
สามารถยอมรับได้ในแอปพลิเคชันของคุณ แต่ฉันคิดว่าคุณอาจมี modal หลายชนิด (เช่น modal ข้อมูล, modal ยืนยัน, ฯลฯ ) และหลายสไตล์สำหรับพวกเขา
การเข้าถึงและการซ่อนคลิกที่ด้านนอกหรือปุ่ม Escape
ส่วนที่สำคัญสุดท้ายเกี่ยวกับ modals คือโดยทั่วไปแล้วเราต้องการซ่อนพวกเขาเมื่อผู้ใช้คลิกนอกหรือกด Escape
แทนที่จะให้คำแนะนำกับคุณเกี่ยวกับการดำเนินการนี้ฉันขอแนะนำให้คุณไม่ใช้ด้วยตนเอง เป็นการยากที่จะพิจารณาการเข้าถึงที่ถูกต้อง
แต่ฉันขอแนะนำให้คุณใช้สามารถเข้าถึงได้ปิด -the-shelf react-modal
กิริยาส่วนประกอบเช่น มันสามารถปรับแต่งได้อย่างสมบูรณ์คุณสามารถใส่ทุกอย่างที่คุณต้องการได้ แต่มันจัดการการเข้าถึงได้อย่างถูกต้องเพื่อให้คนตาบอดยังคงสามารถใช้คำกริยาของคุณได้
คุณสามารถห่อreact-modal
ของคุณเอง<Modal>
ที่ยอมรับอุปกรณ์ประกอบฉากเฉพาะสำหรับแอปพลิเคชันของคุณและสร้างปุ่มลูกหรือเนื้อหาอื่น ๆ มันเป็นแค่ส่วนประกอบ!
แนวทางอื่น ๆ
มีมากกว่าหนึ่งวิธีที่จะทำ
บางคนไม่ชอบการใช้คำฟุ่มเฟือยของวิธีการนี้และชอบที่จะมี<Modal>
ส่วนประกอบที่สามารถแสดงผลภายในส่วนประกอบด้วยเทคนิคที่เรียกว่า "พอร์ทัล" พอร์ทัลช่วยให้คุณแสดงองค์ประกอบภายในของคุณในขณะที่จริงมันจะแสดงผลในสถานที่ที่กำหนดไว้ใน DOM ซึ่งสะดวกมากสำหรับ modals
ในความเป็นจริงreact-modal
ฉันเชื่อมโยงกับก่อนหน้านี้แล้วว่าภายในดังนั้นในทางเทคนิคคุณไม่จำเป็นต้องแสดงมันจากด้านบน ฉันยังพบว่ามันดีที่จะแยกโมดอลที่ต้องการแสดงจากส่วนประกอบที่แสดง แต่คุณสามารถใช้react-modal
โดยตรงจากส่วนประกอบของคุณและข้ามสิ่งที่ฉันเขียนด้านบนไปส่วนใหญ่
ฉันขอแนะนำให้คุณพิจารณาทั้งสองวิธีทดลองกับพวกเขาและเลือกสิ่งที่คุณพบว่าใช้ได้ผลดีที่สุดสำหรับแอปและทีมของคุณ