Javascript Redux不';不要重新渲染组件

Javascript Redux不';不要重新渲染组件,javascript,reactjs,redux,react-redux,Javascript,Reactjs,Redux,React Redux,我有一个组件,它从mapstatetrops()方法获取数据。组件代码为: handleClick = () => { if (this.props.data.status) { this.props.changeIpStatus(index, !this.props.data.status); } else { this.props.changeIpStatus(index, !this.props

我有一个组件,它从
mapstatetrops()
方法获取
数据。组件代码为:

    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>
        )
    }
}
当我单击switcher时,它应该重新渲染,因为数据已更改。我通过控制台日志看到数据发生了更改。但它不会调用重新渲染。为什么?我的组件具有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.

let newState=Object.assign({},state);// 问题在于对象的深度复制。在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.

let newState=Object.assign({},state);// 您可以使用
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;
第二种选择是这样的。不映射所有的
点击
我们可以使用
对象。为
点击
指定

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;

您可以使用
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;
第二种选择是这样的。不映射所有的
点击
我们可以使用
对象。为
点击
指定

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;

我不是百分之百确定,但我担心您在reducer case
CHANGE\u IP\u STATUS
Object.assign
不深度克隆对象)中正在改变您的状态,有没有关于如何深度克隆的建议?
JSON.parse(JSON.stringify(state))
从“lodash/deepClone”导入deepClone
如果您提供BlockSwitcher组件的全部代码(可能省略不相关的功能),则调试会更容易。您可以通过console.log看到数据的变化,但是您在哪里编写了console.log()?为了确定数据在其生命周期中是如何处理的(可能是哪里出了问题),这一点非常重要。我不是100%确定,但我担心在这种情况下,您正在改变您的状态
CHANGE\u IP\u STATUS
Object.assign
不是深度克隆对象)有没有建议如何深度克隆?
JSON.parse(JSON.stringify(state))
从'lodash/deepClone'导入deepClone
如果提供BlockSwitcher组件的整个代码(可能省略不相关的函数),那么调试会更容易。您还可以通过console.log看到数据的变化,但是您在哪里编写了console.log()?为了确定数据在整个生命周期中是如何处理的(以及在哪里出错),这一点非常重要。是否
clicks
属性是数组?@devserkan是的,然后让我另一个备选答案。因为如果所有状态属性都不可序列化,则此方法不起作用。您可以使用扩展运算符
const newState={…state}
@sridharredy spread操作符将完成深度复制的工作吗?
clicks
属性是数组吗?@devserkan是的,然后让我给出另一个备选答案。因为如果所有状态属性都不可序列化,此方法不起作用。您可以使用spread操作符
const newState={…state}
@sridharred spread operator将通过深度复制来完成这项工作?