【发布时间】:2016-12-03 15:41:03
【问题描述】:
我无法弄清楚如何组合 ui 小部件减速器和串联反应渲染树,这样我以后可以使用 react-redux 将减速器的结果 redux 存储映射到渲染树中的道具。
假设这样的设置。我正在尝试制作一个可以在任何应用程序中的任何位置使用的 NameWidget:
NameView.jsx:
...
render() {
return <div> Name: {this.props.name} </div>;
}
...
====
NameAction.js:
...
export const CHANGE_NAME = 'CHANGE_NAME';
...
export function changeNameAction(newName) {
return {
type: CHANGE_NAME,
payload: newName,
};
}
====
NameReducer.js:
import { CHANGE_NAME } from './NameAction';
function ui(state = {name: ''}, action) {
switch(action.type) {
case(CHANGE_NAME):
return Object.assign({}, state, {name: action.payload});
break;
default:
return state;
}
}
export default ui;
====
NameWidget.js:
import { connect } from 'react-redux';
import { NameView } from './NameView';
const mapStateToProps = (state) => {
return {
name: state.name,
};
};
const NameWidget = connect(
mapStateToProps
)(NameView);
export default NameWidget;
如果我直接使用 NameWidget 就没有问题了:
NameApp.jsx:
import { createStore } from 'redux';
import app from './NameReducers';
let store = createStore(app);
...
function render() {
return (
<Provider store={store}>
<NameWidget/>
</Provider>
);
}
但是,我不知道如何制作这个模块化。我实际上不能将这个小部件放入其他任何东西。假设我想这样做:
EncapsulatingView.jsx:
...
render() {
return (
<div>
<NameWidget/>
<SomeOtherReduxWidget/>
</div>
);
}
...
====
EncapsulatingReducer.js:
import { combineReducers } from 'redux'
import nameWidget from '../name/NameReducer';
import someOtherWidget from '../someOther/SomeOtherReduxWidgetReducer';
export default combineReducers({nameWidget, someOtherWidget});
(我希望剩下的代码包括用于封装 * 的 connect() 和 createStore() 是显而易见的。)
这几乎有效,只要所有封装视图中的所有操作都具有唯一类型。但问题是 NameWidget 的 mapStateToProps;它需要从上面更改以使用新路径到其商店部分:
...
const mapStateToProps = (state) => {
return {
name: state.nameWidget.name,
};
};
...
等等 - 取决于祖先如何结合Reducers() 来定义他们更大的超级小部件和应用程序,后代必须以某种方式改变他们的 mapStateToProps() 来补偿。这破坏了代码的封装和可重用性,我看不出如何在 react-redux 中解决它。如何通过组合 combineReducers() 来定义小部件,然后将生成的 store 映射到这些小部件的 props,以一种写一次就用的方式?
(毫无疑问,重复的 combineReducers() 创建一个自下而上的形状似乎很奇怪,但 mapStateToProps() 似乎假设采用自上而下的“绝对路径”方法来查找该形状。)
【问题讨论】:
-
您打算将此代码导出到另一个项目,还是打算在同一项目的另一个设置中重新使用该小部件?
-
短期是特定于项目的,但如果有一个好的模式/解决方案,希望它会支持两者。
-
你有没有看过 redux-form 他们使用定义的名称(表单)作为他们自己的 root-reducer。这样,组件将查看 state.form 的所有值。
标签: reactjs redux react-redux