从 redux 存储的列表中删除项目并重定向回列表 - 延迟道具评估?
Posted
技术标签:
【中文标题】从 redux 存储的列表中删除项目并重定向回列表 - 延迟道具评估?【英文标题】:Removing item from redux-stored list and redirect back to list - delay props evaluating? 【发布时间】:2016-08-29 19:01:28 【问题描述】:我正在查看步骤列表。每个步骤都可以从“查看”屏幕中“查看”和“删除”。
我的StepDetails
组件通过使用简单的steps.find(...)
从存储的steps
部分获取相应的步骤来绑定到redux 存储:
const mapStateToProps = (state, ownProps) =>
let stepId = ownProps.params.stepId;
let step = state.steps.find(s => s.id === stepId);
return step;
;
现在,当我(从“详细信息”中)点击“删除步骤”时,我希望将此步骤从商店中删除,并且我想导航到列表视图。
在删除时调用了 redux 操作,它返回新的步骤列表而没有删除这个,然后调用重定向:
const deleteStep = (stepId) =>
return dispatch =>
return stepsApi.deleteStep(stepId).then(steps =>
dispatch(action(STEPS_LIST_CHANGED, steps));
// react-router-redux action to redirect
dispatch(redirectToList());
)
;
这很好,可以满足我的要求,但有一个缺点:当调用 STEPS_LIST_CHANGED
操作并从列表中删除 step 时,我的组件的 mapStateToProps
在此重定向之前被调用。结果是mapStateToProps
显然无法再找到此步骤,并且我的组件给我错误提示步骤未定义等。
我可以做的是检查是否定义了提供给组件的步骤,如果不渲染任何内容等。但这是一种我不太喜欢的防御性编程风格,因为我不希望我的组件知道什么如果它得到错误的数据怎么办。
我也可以交换动作调度顺序:先重定向然后改变状态,但是感觉也不对(逻辑上你想先删除然后重定向)。
你如何处理这种情况?
编辑:
我最终的结果是将这个 null/undefined-check 放入容器组件(一个执行 redux 接线的组件)。使用这种方法,我不会用不必要的逻辑来混淆我的演示组件。它也可以被抽象为更高阶的组件(或可能是 ES7 装饰器)以在某些必需的道具不存在时呈现 null
或 <div></div>
。
【问题讨论】:
【参考方案1】:我可以想到两种方法:
委派列表更改为重定向?例如:
dispatch(redirectToList(action(STEPS_LIST_CHANGED, steps)));
处理空步组件忽略渲染:
shouldComponentUpdate: function()
return this.state.steps != null;
【讨论】:
【参考方案2】:你可以把你的return语句改成一个数组
const mapStateToProps = (state, ownProps) =>
let stepId = ownProps.params.stepId;
let step = state.steps.find(s => s.id === stepId);
return step ? [step] : []
;
这样你就可以在你的组件上做一个step.map()
并渲染它。
【讨论】:
对我来说感觉太hacky了,这个单元素数组在那里完全是人造的,没有提供太多价值但会给意图可读性带来噪音 @MichalOstruszka 实际上,您可能会在许多 API 上发现这一点,并且在您的函数保持纯净的同时,它的方法仍然有效。【参考方案3】:您面临的问题是您需要一个原子操作来执行删除和重定向。这是不可能的,因为 Redux 存储和 URL 是 two separate states,无法一次更新。
因此,用户可以在短时间内看到:
重定向前的空实体详细信息页面或 重定向后列表中删除的实体。解决这个问题的一种方法是使用React.memo
(或shouldComponentUpdate
)并防止在实体消失后组件重新渲染:
const entityWasDeleted = (prevProps, nextProps) =>
prevProps.entity !== undefined && nextProps.entity === undefined
export default React.memo(EntityDetailComponent, entityWasDeleted)
这有点 hacky,因为 React.memo
不应该像这样使用,但是组件会在下一步中卸载,所以谁在乎呢。
【讨论】:
以上是关于从 redux 存储的列表中删除项目并重定向回列表 - 延迟道具评估?的主要内容,如果未能解决你的问题,请参考以下文章