[英]Redux doesn't re-render the components
我有一个从mapStateToProps()
方法获取data
的组件。 组件的代码是:
handleClick = () => {
if (this.props.data.status) {
this.props.changeIpStatus(index, !this.props.data.status);
} else {
this.props.changeIpStatus(index, !this.props.data.status);
}
}
render() {
if (this.props.data.status) {
this.switchClasses = `switcher blocked`;
this.dotClasses = `dot blocked`;
} else {
this.switchClasses = `switcher`;
this.dotClasses = `dot`;
}
return (
<div className="block">
<div onClick={this.handleClick} className={this.switchClasses}>
<div className={this.dotClasses}></div>
</div>
</div>
)
}
}
我的Redux
连接看起来像:
const mapStateToProps = (state) => ({
data: state.ipTable.data.clicks,
})
const mapDispatchToProps = (dispatch) => {
return {
changeIpStatus: (index, status) => {
return dispatch(changeIpStatus(index, status));
},
}
}
export default connect(mapStateToProps, mapDispatchToProps)(BlockSwitcher)
当我单击切换器时,它应该重新呈现,因为数据已更改。 我看到数据已通过控制台日志更改。 但是它不会调用重新渲染。 为什么? 我的组件具有mapStateToProps,其中包含更改和操作导入正确(选中)的数据。
更新:这是我的减速器:
const initialState = {
data: {}
}
const ipReducer = (state = initialState, action) => {
switch (action.type) {
case `SET_CLICKS`:
return {
...state,
data: action.data
}
case `CHANGE_IP_STATUS`:
let newState = Object.assign({}, state);
newState.data.clicks[action.index].status = action.status;
return newState;
default: return state;
}
}
export default ipReducer;
问题在于对象的深拷贝。 在JavaScrip中,用于复制对象而在它们之间没有任何引用的情况下,我们必须使用例如:
let newState = JSON.parse(JSON.stringify(state));
不是这个:
let newState = Object.assign({}, state); // <-- this is do not return a standalone new object. Do not use it in your reducer.
感谢@kind用户!
PS: 本文带有示例,为什么在这种情况下Object.assign()无法正常工作。
您可以使用JSON.parse(JSON.stringify(...))
方法,但是请注意,如果您的状态包含不可序列化的属性,则会丢失该属性。
这是另一种方法。 您可以更频繁地看到此方法。
// map the clicks, if index match return the new one with the new status
// if the index does not match just return the current click
const newClicks = state.data.clicks.map((click, index) => {
if (index !== action.index) return click;
return { ...click, status: action.status };
});
// Here, set your new state with your new clicks without mutating the original one
const newState = { ...state, data: { ...state.data, clicks: newClicks } };
return newState;
第二种选择就是这样。 在不映射所有clicks
我们可以使用Object.assign
进行clicks
突变。
const newClicks = Object.assign([], state.data.clicks, {
[action.index]: { ...state.data.clicks[action.index], status: action.status }
});
const newState = { ...state, data: { ...state.data, clicks: newClicks } };
return newState;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.