Redux不会重新渲染组件

时间:2018-11-30 15:21:54

标签: javascript reactjs redux react-redux

我有一个从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)

2 个答案:

答案 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;