Önerdiğim yaklaşım biraz ayrıntılı ama karmaşık uygulamalara oldukça iyi ölçeklendiğini buldum. Bir model göstermek istediğinizde, hangi modeli görmek istediğinizi açıklayan bir işlem başlatın :
Kipi Göstermek için Bir Eylem Gönderme
this.props.dispatch({
type: 'SHOW_MODAL',
modalType: 'DELETE_POST',
modalProps: {
postId: 42
}
})
(Dizeler elbette sabit olabilir; basitlik için satır içi dizeler kullanıyorum.)
Kalıcı Durumu Yönetmek İçin Bir Redüktör Yazma
Ardından, yalnızca bu değerleri kabul eden bir redüktörünüz olduğundan emin olun:
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 */
})
Harika! Şimdi, bir eylem gönderirken, state.modal
o anda görünür mod penceresi hakkında bilgileri içerecek şekilde güncellenecektir.
Kök Kalıcı Bileşenin Yazılması
Bileşen hiyerarşinizin köküne <ModalRoot>
, Redux deposuna bağlı bir bileşen ekleyin . state.modal
Uygun bir mod bileşenini dinleyecek ve görüntüleyecektir 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)
Burada ne yaptık? ModalRoot
akımını okur modalType
ve modalProps
gelenstate.modal
hangi bağlı olduğu, ve karşılık gelen bir bileşen gibi işler DeletePostModal
ya da ConfirmLogoutModal
. Her model bir bileşendir!
Belirli Modal Bileşenleri Yazma
Burada genel bir kural yok. Bunlar sadece eylemleri gönderebilen, mağaza durumundan bir şeyler okuyabilen ve sadece modals olabilen React bileşenleridir. .
Örneğin, DeletePostModal
şöyle görünebilir:
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
O Yayın başlığını görüntülemek ve herhangi bir bağlı bileşen gibi çalışır böylece deposuna bağlı: o dahil eylemleri sevk edebilirhideModal
kendisini gizlemek için gerektiğinde.
Sunum Bileşenini Çıkarma
Her "özel" mod için aynı yerleşim mantığını kopyalayıp yapıştırmak zor olur. Ama bileşenleriniz var, değil mi? Böylece bir sunum çıkarabilirsiniz <Modal>
nasıl göründükleri yapmak özellikle neyi modals bilmez bileşeni ama kolları.
Ardından, DeletePostModal
oluşturma için kullanabileceğiniz gibi belirli modüller :
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)
Bir dizi sahne bulmak size kalmış <Modal>
Başvurunuzda kabul edebilecek , ancak birkaç çeşit modalın (örneğin bilgi modal, onay modal, vb.) Ve onlar için çeşitli stiller olabileceğini düşünürüm.
Erişilebilirlik ve Tıklama Dışında veya Kaçış Anahtarında Gizleme
Modals ile ilgili son önemli kısım, genellikle kullanıcı dışarıya tıkladığında veya Escape tuşuna bastığında onları gizlemek istiyoruz.
Size bunu uygulamakla ilgili tavsiyelerde bulunmak yerine, sadece kendiniz uygulamamanızı öneririm. Erişilebilirliği göz önünde bulundurarak doğru olmak zordur.
Bunun yerine, erişilebilir bir kullanıma hazır mod bileşenini kullanmanızı öneririm react-modal
. Tamamen özelleştirilebilir, içine istediğiniz her şeyi koyabilirsiniz, ancak kör insanların yine de modalınızı kullanabilmeleri için erişilebilirliği doğru şekilde işler.
Uygulamalarınız için özel sahne kabul eden ve alt düğmeler veya başka içerikler üreten react-modal
kendi başınıza bile sarmalayabilirsiniz <Modal>
. Hepsi sadece bileşenler!
Diğer Yaklaşımlar
Bunu yapmanın birden fazla yolu var.
Bazı insanlar bu yaklaşımın ayrıntı düzeyini sevmezler ve “portal” adı verilen bir teknikle bileşenlerinin içinde<Modal>
oluşturabilecekleri bir bileşeni tercih ederler . Portallar, aslında bir bileşeni kendi içinizde oluşturmanıza izin verir DOM'da önceden belirlenmiş bir yerde renderlenecek, bu da modals için çok uygun.
Aslında react-modal
daha önce bağlandım, bunu dahili olarak çok teknik olarak yapıyorum, hatta yukarıdan oluşturmanıza bile gerek yok. Göstermek istediğim modalı gösteren bileşenden ayırmayı hala güzel buluyorum, ancak react-modal
doğrudan bileşenlerinizden de kullanabilir ve yukarıda yazdıklarımın çoğunu atlayabilirsiniz.
Her iki yaklaşımı da düşünmenizi, onlarla denemenizi ve uygulamanız ve ekibiniz için en uygun olanı seçmenizi öneririm.