我有一个进行API调用,然后通过reducer更新状态的组件。问题是,这不能很好地工作,因为组件中的数据没有得到更新,这就像反应没有注意到状态改变而从未重新渲染组件一样,但是我不确定这是否是真正的问题在这里。因此该组件如下所示:
class MyComponent extends Component {
componentDidMount() {
// ajax call
this.props.loadData(1);
}
render() {
return (
<Grid>
<MySecondComponent
currentData={this.props.currentData}
/>
</Grid>
);
}
}
const mapStateToProps = state => ({
reducer state.myReducer,
currentData: state.myReducer.currentData
});
const mapDispatchToProps = dispatch => {
return {
loadData: () => {
HttpClient.getData(id, (data) => {
dispatch(
action_loadCurrentData(
data
)
);
});
},
};
};
export default connect(
mapStateToProps,
mapDispatchToProps
)(MyComponent);
我在这里做两件事:在安装组件后立即发出API调用,然后在获取数据后调度action_loadCurrentData
此操作如下:
//动作
export function action_loadCurrentData(
data
) {
return {
type: 'LOAD_CURRENT_DATA',
payload: {
currentData: data,
}
};
}
和减速器:
//减速器
const defaultState = {
};
const reducer = (state = defaultState, action) => {
switch (action.type) {
case 'LOAD_CURRENT_DATA':
state = {
...state,
currentData: {
myData: {
...state.currentData.myData,
0: action.payload.currentData
}
}
};
}
};
export default myReducer;
所以这里的问题是,我传递给this.props.currentData
的{{1}}最终将为空,好像我根本没有设置数据一样。但是,如果我在调试器中停止执行并花几秒钟的时间,数据将被正确填充,因此我不确定在这里做错了什么吗?
答案 0 :(得分:2)
不要重新分配状态,而是返回新创建的对象
const reducer = (state = defaultState, action) => {
switch (action.type) {
case 'LOAD_CURRENT_DATA':
return {
...state,
currentData: {
myData: {
...state.currentData.myData,
0: action.payload.currentData
}
}
};
}
};
您的reducer需要返回新的状态对象,该对象必须是与先前状态不同的实例才能触发组件更新。
reduceer是一个纯函数,它具有上一个状态和一个动作,并返回下一个状态。
还有
您在简化器中绝不做的事情:
- 更改其参数;
- 执行副作用,例如API调用和路由转换;
- 调用非纯函数,例如Date.now()或Math.random()。