我偶然发现了一个需要单个JSON“定义”对象渲染的vanilla JS webapp部分的要求。定义已加载,最初通过HTTP
请求 ,读取,解析并传递到应用的另一层。对象本身在其整个生命周期中永远不会改变。
我现在正尝试使用ReactJS + Redux在redux-thunk中对此方案进行建模。我创建了一个thunk / async动作来获取JSON对象,提取它所需要的东西并最终用它来更新状态 - 但它不会将对象本身存储在状态中。这似乎是正确的逻辑方法,因为如上所述,定义永远不会以任何方式被修改。从严格意义上讲,我认为它只是 not state 。
然而,通过做出这个决定,我在实施实际React.Component
时最终陷入困境。几乎每一个example我都在野外看到过像这样的异步案例:
this.props
和mapStateToProps
将该属性映射到组件中的connect
。就我而言,我实际上没有要绑定到的州属性。所以我最终在异步操作中返回定义对象,并使用组件的本地状态来获取我需要的东西。
class ContainerComponent extends React.Component {
state = { definitions: {} };
componentDidMount() {
const { dispatch } = this.props;
dispatch(fetchDefinitions())
.then((definitions) => this.setState({ definitions }));
}
render() {
return (<PresentationalComponent definitions={this.state.definitions} />);
}
}
export default connect()(ContainerComponent);
不是说this.setState
应该be avoided,但这看起来非常像我之前甚至介绍Redux :一个API调用返回一个承诺 - 只有一个更多的干涉间接。
componentDidMount() {
const { dispatch } = this.props;
fetch(`${API_URL}/definitions`)
.then((res) => res.json())
.then((definitions) => this.setState({ definitions }));
}
那么,我应该怎么做呢?这里有什么特别的东西吗?我应该遵循的任何模式?也许,完全避免Redux这件事?
答案 0 :(得分:2)
你是对的,拥有一个组件状态并不一定是件坏事,但我相信你对API调用后存储数据的位置感到困惑。
你提到它不一定是州,但我会反驳。在进行API调用之前,您的应用程序没有该数据。在应用程序启动时,您可能会有某些UX / UI指示,例如,可能指示是否正在获取数据:definitions.all.isFetching
。
在componentDidMount
中,调度操作以获取数据是正确的。一旦触发了操作,并且收到了成功响应,您的reducer应该将定义保存到您的redux商店,如
import { assign, get } from 'lodash';
const all = (
state = { isFetching: false, data: [] },
action,
) => {
switch (action.type) {
case types.LIST_DEFINITIONS:
return assign({}, state, { isFetching: true });
case types.LIST_DEFINITIONS_SUCCESS:
return assign({}, state, get(action, 'result.data'), { isFetching: false });
default: return state;
}
};
然后在您的组件中,您将connect
您的redux商店
function mapStateToProps(state){
return {
definitions: state.definitions.all.data
};
}
export default connect(mapStateToProps, { listDefinitions })(ContainerComponent);
另请注意,我在我的示例中移动了操作,并将其放入与mapDispatchToProps
简写的连接中。