这是一个之前已经讨论过的主题,但我仍然没有找到我喜欢的答案,并且会喜欢一些建议。
我遇到以下问题。我的应用程序包含一个名为CREATE_RESPONSE
的操作,该操作会创建一个新的响应记录并将其推送到responses
状态。当用户单击按钮时,将从我的组件调度此操作的操作创建者。
onClick={() => {
this.props.createResponse();
}}
现在,在用户执行此操作后,我想为此新响应打开一个模式。此模式依赖于新的响应状态更改,因此必须在createResponse
之后发生。
对我来说最直观的解决方案是使用回调,但我相信这代表了Redux的反模式。
另一种方法是监听响应状态更改,然后在响应数量发生变化时调度操作(类似于订阅示例:http://redux.js.org/docs/api/Store.html#subscribe)
function responses(state) {
return state.responses.size
}
let currentValue
function handleChange() {
let previousValue = currentValue
currentValue = responses(store.getState())
if (previousValue !== currentValue) {
// Dispatch action here
}
}
store.subscribe(handleChange)
这里的问题是我们正在响应满足这种条件的所有状态变化。在我的应用中,这在页面加载时被错误地触发。
所以我的问题归结为:为响应状态变化而派遣行动的最佳方式是什么?
修改
以下是我的Modal和Response reducer的简化版本:
模态
const modalState = Immutable.Map({
isOpen: false,
view: null,
modalProps: {}
});
export const modal = (state = modalState, action) => {
switch (action.type) {
...
}
}
响应
const responseRecord = Immutable.Record({
id: null,
...
});
export const responses = (state = Immutable.List([]), action) => {
switch (action.type) {
case 'CREATE_RESPONSE':
newResponse = new responseRecord(...);
state = state.unshift(newResponse);
return state;
...
答案 0 :(得分:1)
您可以在Modal reducer中设置CREATE_RESPONSE
个案例。每个动作都会通过每个减速器运行。大多数情况下,它会很快达到默认值。但如果您愿意,可以听取CREATE_RESPONSE
并将isOpen
设置为true。
虽然我也不认为这是必要的。您可以将isOpen
添加到全局状态,而不是newRecord
标志。将模态定义为:
<Modal show={this.props.newRecord}...
并清除模态在关闭时调度的任何操作中的newRecord
。可能有必要在responses
减速器中听取该动作,但这是合法的。
(我有点快速和松散,因为newRecord
不是布尔值。它应该可以工作,但你也可以强制它为布尔值{{1} },或直接检查无效)
这应解决在页面加载时打开它的问题。模态完全符合它应该做的事情:只要有新记录就开放,没有任何明确的命令。您只需让React管理其可见性。