首页 文章

什么是触发组件重新渲染

提问于
浏览
0

所以,在我的reducer中有一些看起来像这样的代码之前,我的组件没有重新渲染,即使列表正确映射到React道具(通过mapStateToProps):

case "ADDTOLIST":
    let stateCopy = Object.assign({}, state);

    let listsCopy = stateCopy.lists;
    listsCopy.push(action.item);

    return {...state, lists: listsCopy};

然后我只更改了我将listsCopy设置为this的行 - 所以我使用slice创建了lists数组的副本:

let listsCopy = stateCopy.lists.slice();

现在我的组件重新渲染正确!所以我的问题是为什么调用切片触发组件的重新渲染?以前我只是正常分配它 .

我不确定我在这里缺少什么/我不理解什么? “之前”代码中的控制台日志似乎表明正在按预期修改“listsCopy”,但未触发状态更改 .

此外,我正在使用州的副本,而不是改变它 . 我只是不确定为什么切片在这里有所作为?

提前致谢!

1 回答

  • 0

    你正在改变数组 . 使用redux,您必须始终返回您修改的任何内容的新副本 .

    return {...state, lists: [...state.lists, action.item]};
    

    切片工作而不是推送的原因是因为.slice返回数组的新副本 . 推变异 .

    此外,Object.assign的工作方式......它创建了一个新的根对象,但它不能递归地工作 . 需要研究的东西: Value 和参考类型之间的差异 . 值类型包括字符串,数字,布尔值,null或未定义 . 这些东西都是原始值,可以直接比较 . 但是,引用类型类似于对象或数组或自定义类或函数的任何实例 . 从本质上讲,即使它们具有相同的内容,也无法直接进行比较 .

    例如:

    var foo = ['foo']
    var bar = ['foo']
    // foo === bar : false
    
    var a = Object.assign({}, {foo: foo})
    // a.foo === foo : true
    
    var b = Object.assign({}, {foo: foo}, {foo: bar})
    // b.foo === bar : true
    // b.foo === foo : false
    

    基本规则是在主reducer内部有嵌套对象(如数组或对象)的任何时候 - 如果对其进行更改,则必须返回新副本 .

    redux正在发生的事情正如你在 var a 中看到的那样 . 即使您更新了数组的内容,redux也只是对reducer的每个根键进行严格的相等检查,以确定它是否应该更新组件 . 因此,当您返回推送的数组时,它会将该对象视为与先前状态相同 - 因为在两种情况下它都是相同的数组实例 . Redux不考虑数组(或对象)中的内容 .

相关问题