【发布时间】:2017-01-18 14:45:42
【问题描述】:
我尝试使用 redux 和原生 promise 构建一个通用的确认组件。我在这里阅读了 Dan Abramovs 的解决方案:How can I display a modal dialog in Redux that performs asynchronous actions?,但我正在寻找更通用的方法。 基本上我想这样做:
confirm({
type: 'warning',
title: 'Are you sure?',
description: 'Would you like to do this action?',
confirmLabel: 'Yes',
abortLabel: 'Abort'
})
.then(() => {
// do something after promise is resolved
})
confirm 方法基本上是打开 modal 并返回一个 promise。在 promise 中,我订阅了我的 redux 存储,监听状态变化并解决或拒绝 promise:
export const confirm = function(settings) {
// first dispatch openConfirmModal with given props
store.dispatch(
openConfirmModal({
...settings
})
);
// return a promise that subscribes to redux store
// see: http://redux.js.org/docs/api/Store.html#subscribe
// on stateChanges check for resolved/rejected
// if resolved or rejected:
// - dispatch closeConfirmModal
// - resolve or reject the promise
// - unsubscribe to store
return new Promise((resolve, reject) => {
function handleStateChange() {
let newState = store.getState();
if (newState.confirmModal.resolved) {
store.dispatch(closeConfirmModal());
resolve();
unsubscribe();
}
if (newState.confirmModal.rejected) {
store.dispatch(closeConfirmModal());
reject();
unsubscribe();
}
}
let unsubscribe = store.subscribe(handleStateChange);
})
}
我的确认组件已连接到 redux 商店,并且在某种布局组件中包含一次 - 因此它可用于应用程序中的所有路由:
class ConfirmModal extends Component {
constructor(props) {
super(props)
}
confirm() {
this.props.dispatch(resolveConfirmModal());
}
abort() {
this.props.dispatch(rejectConfirmModal());
}
render() {
// my modal window
}
}
export default connect(
state => ({
confirmModal: state.confirmModal
})
)(ConfirmModal);
Reducer/Action 看起来像这样:
export const openConfirmModal = (settings) => {
return {
type: 'OPEN_CONFIRM_MODAL',
settings
};
};
export const resolveConfirmModal = () => {
return {
type: 'RESOLVE_CONFIRM_MODAL'
};
};
export const rejectConfirmModal = () => {
return {
type: 'REJECT_CONFIRM_MODAL'
};
};
export const closeConfirmModal = () => {
return {
type: 'CLOSE_CONFIRM_MODAL'
};
};
const initialState = {
open: false,
type: 'info',
title: 'Are you sure?',
description: 'Are you sure you want to do this action?',
confirmLabel: 'Yes',
abortLabel: 'Abort',
};
export const ConfirmModalReducer = (state = initialState, action) => {
switch (action.type) {
case 'OPEN_CONFIRM_MODAL':
return { ...action.settings, open: true };
case 'RESOLVE_CONFIRM_MODAL':
return { ...state, resolved: true };
case 'REJECT_CONFIRM_MODAL':
return { ...state, rejected: true };
case 'CLOSE_CONFIRM_MODAL':
return initialState;
default:
return state;
}
};
redux 部分正在工作。我的确认窗口可以打开/关闭并根据我的选项进行渲染。但是我如何在我的确认方法中定义一个可以在我的组件中解决的承诺?我如何将所有东西连接起来?
找到一个可行的解决方案!
找到了一个几乎是我正在寻找的解决方案:
- 模态属性由我的 Redux 状态驱动
- 模态组件只包含一次,它就存在于我的 应用程序不是像其他渲染的应用程序一样 这里:http://blog.arkency.com/2015/04/beautiful-confirm-window-with-react/
- confirm 方法返回一个本地承诺,即 由 Redux 状态驱动的已解决/拒绝
你怎么看?
【问题讨论】:
-
可以加
closeConfirmModal()代码吗? -
完成。添加了动作和减速器。也许使用异步操作会更好。但到目前为止,我试图在 redux 部分保持简单。
-
@d-bro82 你有这个例子用 javascript 代替 cofeescript 吗?
标签: reactjs redux react-redux