我有一个从loadtext[0]
方法中提取data
的组件。组件的代码是:
mapStateToProps()
我的 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
当我单击切换器时,它应该重新呈现,因为数据已更改。我看到数据已通过控制台日志更改。但是它不会调用重新渲染。为什么?我的组件具有mapStateToProps,其中包含更改和操作导入正确(选中)的数据。
更新: 这是我的减速器:
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)
答案 0 :(得分:1)
问题在于对象的深层复制。在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用户!
P.S这是一个article,其中包含Object.assign()在这种情况下不起作用的示例。
答案 1 :(得分:1)
您可以使用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;