繁体   English   中英

Redux不会重新渲染组件

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM