【发布时间】:2017-11-22 08:04:28
【问题描述】:
在我的 redux 容器中,我必须调度相当复杂的操作,从存储中获取大量属性。在不破坏性能的情况下,我找不到合适的模式来解决问题。
让我们以只包含发送按钮来发送消息的容器为例:
(对于这样一个小例子,以下任何一种方法都可以很好地工作,我只是想说明我在更大的容器中遇到的问题。)
朴素的方法 - 将所有参数传递给组件
function mapStateToProps(state) {
return {
user: selectors.selectedUser(state),
title: selectors.title(state),
message: selectors.message(state),
};
}
function dispatchProps(state) {
return {
onClickSend: function(user, title, message) {
actions.sendMessage({user, title, message});
}
};
}
如果我这样做,我的简单发送按钮将不得不注意很多无用的属性:
SendBtn.propTypes = {
user: PropTypes.string,
title: PropTypes.string,
message: PropTypes.string,
onClickSend: PropTypes.func,
}
还可以使用所有这些道具调用 onClickSend:
onClickSend(user, title, message)
对于“发送”按钮来说,这太过分了。当我们点击它时,按钮应该只知道它必须调用onClickSend,这个组件是一个简单的按钮。它不应该知道任何其他道具。此外,在更复杂的情况下,可能不仅需要 2 个道具(标题和消息),还需要 5 个或 10 个。
另一个问题是性能,每次我要修改消息或标题(每次击键时===),发送按钮都会重新渲染。
我目前的方法 - 使用 mergeProps 将参数传递给操作
我的应用当前使用的方法是依赖于mergeProps:
function mapStateToProps(state) {
return {
user: selectors.selectedUser(state),
title: selectors.title(state),
message: selectors.message(state),
};
}
function mergeProps(stateProps, dispatchProps, ownProps) {
const {user, title, message} = stateProps;
const newProps = {
onClickSend: actions.sendMessage.bind(null, {
user,
title,
message
});
};
return R.mergeAll([stateProps, dispatchProps, ownProps, newProps]);
}
我发现这种方法更好,因为发送按钮只需要知道它必须触发其独特的属性:单击时的 onClickSend。无需担心用户、标题或消息。
但是,这种方法有一个巨大的缺点:onClickSend 的引用会在每次商店更改时发生变化,这会导致在更大的实际案例中性能非常差。
第三种方法 - 从 redux-thunk 访问状态
性能问题的解决方案可能是使用 redux-thunk 并直接在操作中访问状态。
// Action file
var sendMessageAction = createAction("SEND_MESSAGE", function(dispatch, getState) {
// executed by redux thunk
const state = getState();
const args = {
user: selectors.selectedUser(state),
title: selectors.title(state),
message: selectors.message(state),
}
dispatch(sendMessage(args))
})
// Container file
function mapDispatchToProps(dispatch) {
onClickSend: dispatch(sendMessageAction())
}
但我不喜欢这种方法,因为:
- 操作会访问商店 - 它不会破坏单向流吗?
- 动作会知道选择器 - 关注点分离不好?
- 动作会变成复杂的对象
你的方法
我现在已经在一个大型 redux 应用程序上工作了一段时间,这是迄今为止我在使用 Redux 时遇到的最大痛苦。令人惊讶的是,我没有找到太多关于如何解决它的信息,所以我想知道我是否遗漏了一些基本的东西。
你解决这个问题的方法是什么?
【问题讨论】:
标签: javascript reactjs redux