Javascript Redux:私人/公共选择器的更好方式
正如所建议的,私有选择器作为公共选择器重复使用,以在完整状态下使用Javascript Redux:私人/公共选择器的更好方式,javascript,redux,react-redux,Javascript,Redux,React Redux,正如所建议的,私有选择器作为公共选择器重复使用,以在完整状态下使用 切片上使用的专用选择器 在完全状态下使用的公共选择器 但这将导致: 重复代码 在公共选择器的命名空间中溢出 有没有更好的方法来组织选择器? 原始示例: 根还原器和公共选择器: // reducers/index.js import todos, * as fromTodos from './todos'; // Reducer export default combineReducers({ todos });
- 切片上使用的专用选择器
- 在完全状态下使用的公共选择器
- 重复代码
- 在公共选择器的命名空间中溢出
// reducers/index.js
import todos, * as fromTodos from './todos';
// Reducer
export default combineReducers({
todos
});
// Private selector
getVisibleTodos(state, filter) {
return fromTodos.getVisibleTodos(state.todos, filter);
}
// reducers/todos.js
// Reducer
export default (state, action) => {
switch(action.type){
case 'ADD_TODO':
// ...
break;
// Handle other actions ...
}
}
// Private selector
getVisibleTodos(state, filter) {
switch(filter) {
case 'all':
return todos;
case 'completed':
return state.filter(t => t.completed);
// Other cases ...
}
}
const mapStateToProps = (state, {params}) => ({
todos: getVisibleTodos(state, params.filter || 'all')
});
切片缩减器和专用选择器:
// reducers/index.js
import todos, * as fromTodos from './todos';
// Reducer
export default combineReducers({
todos
});
// Private selector
getVisibleTodos(state, filter) {
return fromTodos.getVisibleTodos(state.todos, filter);
}
// reducers/todos.js
// Reducer
export default (state, action) => {
switch(action.type){
case 'ADD_TODO':
// ...
break;
// Handle other actions ...
}
}
// Private selector
getVisibleTodos(state, filter) {
switch(filter) {
case 'all':
return todos;
case 'completed':
return state.filter(t => t.completed);
// Other cases ...
}
}
const mapStateToProps = (state, {params}) => ({
todos: getVisibleTodos(state, params.filter || 'all')
});
使用选择器:
// reducers/index.js
import todos, * as fromTodos from './todos';
// Reducer
export default combineReducers({
todos
});
// Private selector
getVisibleTodos(state, filter) {
return fromTodos.getVisibleTodos(state.todos, filter);
}
// reducers/todos.js
// Reducer
export default (state, action) => {
switch(action.type){
case 'ADD_TODO':
// ...
break;
// Handle other actions ...
}
}
// Private selector
getVisibleTodos(state, filter) {
switch(filter) {
case 'all':
return todos;
case 'completed':
return state.filter(t => t.completed);
// Other cases ...
}
}
const mapStateToProps = (state, {params}) => ({
todos: getVisibleTodos(state, params.filter || 'all')
});
将私有选择器复制为公共选择器有一些优点和缺点 我相信复制在分离关注点和封装逻辑方面对您有好处,也就是说,无论何时您必须更改从redux状态获取某些数据的逻辑,您都不必修改您的组件。 此外,您的组件不应该拥有对与其相关的状态部分进行切片的逻辑 然而,它确实会导致一些不必要的重复。 我可以想出一个带有库的解决方案,但它可能需要您在单独的文件中列出所有选择器。 使用glob,您可以遍历选择器文件夹中的所有js文件(您可以增加复杂性,忽略某些文件查看其实例原型,或者其他文件),并将它们合并到根reducer文件中。 我在express应用程序中见过这种技术,通过为每条路线创建一个js文件,将所有路线组装在一个地方 希望它的清晰和帮助你
编辑-->我强烈建议您仔细查看一下,以全面了解为什么在root reducer中将私有选择器复制为公共选择器是有益的(尽管我知道您开始认为您也可以将公共选择器放置在单独的文件中…)你能提供一个有效的例子吗?我已经增强了这个例子。请注意,将选择器重新定义一次为私有选择器,另一次为公共选择器。问题在于避免这种重复。选择器通常是纯函数,因此可以毫无问题地移动到它们自己的模块中。我想从中获得灵感