如何在Redux中显示执行异步操作的模式对话框?

我正在构建一个需要在某些情况下显示确认对话框的应用程序。

假设我要删除某些东西,然后我将分派一个动作,deleteSomething(id)以便某些化简器会捕获该事件并填充对话框化简器以显示它。

当此对话框提交时,我会怀疑。

  • 该组件如何根据分派的第一个动作分派适当的动作?
  • 动作创建者应该处理这种逻辑吗?
  • 我们可以在减速器中添加动作吗?

编辑:

使其更清楚:

deleteThingA(id) => show dialog with Questions => deleteThingARemotely(id)

createThingB(id) => Show dialog with Questions => createThingBRemotely(id)

因此,我试图重用对话框组件。显示/隐藏对话框不是问题,因为这可以在化简器中轻松完成。我要指定的是如何根据在左侧启动流程的动作从右侧调度动作。

回答:

我建议的方法有点冗长,但是我发现它可以很好地扩展到复杂的应用程序中。当你想显示模式,触发一个动作说明 莫代尔你想看到的:

回答:

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将进行更新以包括有关当前可见的模态窗口的信息。

回答:

在组件层次结构的根目录中,添加一个<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读取当前modalTypemodalPropsstate.modal其所连接的,并呈现一个相应的组件,如DeletePostModalConfirmLogoutModal。每个模态都是一个组成部分!

回答:

这里没有一般规则。它们只是React组件,可以调度动作,从存储状态读取某些内容, 。

例如,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>组件,该组件不知道特定的模态做什么,但可以处理它们的外观。

然后,诸如的特定模态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>可以在您的应用程序中接受的一组道具,但是我想您可能会拥有几种模式(例如信息模式,确认模式等)以及它们的几种样式。

回答:

关于模态的最后一个重要部分是,通常我们希望在用户单击外部或按Escape时将其隐藏。

我建议您不要自己实施它,而不是为您提供实施建议。考虑可访问性,很难正确。

相反,我建议您使用 的现成模式组件,例如react-modal。它是完全可定制的,您可以在其中放入任何内容,但是它可以正确处理可访问性,因此盲人仍然可以使用您的模式。

您甚至react-modal可以自己包装<Modal>,接受特定于您的应用程序的道具并生成子按钮或其他内容。全部都是组件!

回答:

有多种方法可以做到这一点。

有些人不喜欢这种方法的冗长性,而是喜欢拥有一个<Modal>组件,他们可以使用称为“门户”的技术

进行渲染。门户让您可以在内部渲染组件,而 实际上 它可以在DOM中的预定位置进行渲染,这对于模态非常方便。

实际上,react-modal我以前链接的内容已经在内部进行过,因此从技术上讲,您甚至不需要从顶部进行渲染。我仍然觉得将要显示的模态与显示它的组件分离是很不错的,但是您也可以react-

modal直接从您的组件中使用它,而跳过上面我写的大部分内容。

我鼓励您考虑两种方法,进行试验,然后选择最适合您的应用和团队的方法。

以上是 如何在Redux中显示执行异步操作的模式对话框? 的全部内容, 来源链接: utcz.com/qa/400944.html

回到顶部