Redux——繁重的工作应该在哪里进行——reducer、action、container 还是 presentation component?
Redux -- where should the heavy lifting happen -- reducer, action, container, or presentation component?
我一直在尝试实施 here 教授的 container/presentational 组件范例。然而,我对我的一些代码应该放在哪里感到有点困惑。
假设我有一个简单的项目列表。单击一项时,应将其从列表中删除。修改列表的代码应该放在我的 reducer、action creator、容器组件还是展示组件中?
减速器:
case 'REMOVE_ITEM':
return Object.assign({}, state, {items: action.value})
动作创作者:
export function removeItem(items) {
return {
type: 'REMOVE_ITEM',
value: items
};
}
现在我们的容器组件:
import ItemsList from './ItemsList';
import { connect } from 'react-redux';
import * as actions from './actions';
var mapStateToProps = function(state) {
return {
items: state.itemsList.items
};
};
var mapDispatchToProps = function(dispatch) {
return {
onItemClicked: function(items) {
dispatch(actions.removeItem(items));
}
};
};
var ItemsListContainer = connect(
mapStateToProps,
mapDispatchToProps
)(ItemsList);
module.exports = ItemsListContainer;
最后是展示部分:
import React from 'react';
module.exports = React.createClass({
showRows: function() {
return this.props.items.map(item => {
return (
<li key={item.id} onClick={this.props.onItemClicked}>{item.title}</li>
);
});
},
render: function() {
return (
<ul>
{this.showRows()}
</ul>
);
}
});
然后,在某些时候,我们需要一些代码来删除列表项。单击项目时,我们需要从项目列表中拼接它。
该代码应该放在哪里?
我可以看到它进入展示组件,然后在修改列表后从容器组件调用 onItemClicked 回调。
我可以看到它在容器组件中运行,因此表示组件尽可能愚蠢。不过,我需要一种访问状态的方法(以获取项目),并且由于我已经将项目作为 props 传递到表示组件中,所以在那里做对我来说更有意义。
我可以看到它在动作创建器中运行,删除的项目作为 removeItem 函数的第二个参数。
将它放在 reducer 中似乎是个坏主意,因为进行大量计算(修改数组)似乎应该在分派操作之前发生,而不是之后。
修改数组的繁重工作应该在哪里进行?它似乎应该放在展示组件中,但我知道那些应该是愚蠢的组件...
你应该这样想:
DumbComponent (View/Accepts Input) -> SmartComponent (RespondsToInput by firing a dispatch) -> ActionCreator(创建必要的动作,必要时提供有效载荷 - 在这种情况下,您需要过滤掉的索引) -> Reducer(通过修改并返回新状态来响应动作。)
在你的 reducer 中你会做类似的事情:
return Object.assign({}, state, { items: state.items.filter((item, index) => index !== payload) });
reducer中的calculations/heavy提升也是如此,如果它修改状态,代码应该在修改状态的地方。
我一直在尝试实施 here 教授的 container/presentational 组件范例。然而,我对我的一些代码应该放在哪里感到有点困惑。
假设我有一个简单的项目列表。单击一项时,应将其从列表中删除。修改列表的代码应该放在我的 reducer、action creator、容器组件还是展示组件中?
减速器:
case 'REMOVE_ITEM':
return Object.assign({}, state, {items: action.value})
动作创作者:
export function removeItem(items) {
return {
type: 'REMOVE_ITEM',
value: items
};
}
现在我们的容器组件:
import ItemsList from './ItemsList';
import { connect } from 'react-redux';
import * as actions from './actions';
var mapStateToProps = function(state) {
return {
items: state.itemsList.items
};
};
var mapDispatchToProps = function(dispatch) {
return {
onItemClicked: function(items) {
dispatch(actions.removeItem(items));
}
};
};
var ItemsListContainer = connect(
mapStateToProps,
mapDispatchToProps
)(ItemsList);
module.exports = ItemsListContainer;
最后是展示部分:
import React from 'react';
module.exports = React.createClass({
showRows: function() {
return this.props.items.map(item => {
return (
<li key={item.id} onClick={this.props.onItemClicked}>{item.title}</li>
);
});
},
render: function() {
return (
<ul>
{this.showRows()}
</ul>
);
}
});
然后,在某些时候,我们需要一些代码来删除列表项。单击项目时,我们需要从项目列表中拼接它。 该代码应该放在哪里?
我可以看到它进入展示组件,然后在修改列表后从容器组件调用 onItemClicked 回调。
我可以看到它在容器组件中运行,因此表示组件尽可能愚蠢。不过,我需要一种访问状态的方法(以获取项目),并且由于我已经将项目作为 props 传递到表示组件中,所以在那里做对我来说更有意义。
我可以看到它在动作创建器中运行,删除的项目作为 removeItem 函数的第二个参数。
将它放在 reducer 中似乎是个坏主意,因为进行大量计算(修改数组)似乎应该在分派操作之前发生,而不是之后。
修改数组的繁重工作应该在哪里进行?它似乎应该放在展示组件中,但我知道那些应该是愚蠢的组件...
你应该这样想:
DumbComponent (View/Accepts Input) -> SmartComponent (RespondsToInput by firing a dispatch) -> ActionCreator(创建必要的动作,必要时提供有效载荷 - 在这种情况下,您需要过滤掉的索引) -> Reducer(通过修改并返回新状态来响应动作。)
在你的 reducer 中你会做类似的事情:
return Object.assign({}, state, { items: state.items.filter((item, index) => index !== payload) });
reducer中的calculations/heavy提升也是如此,如果它修改状态,代码应该在修改状态的地方。