什么是触发组件重新渲染

时间:2017-05-10 01:27:52

标签: javascript arrays react-redux

所以,在我的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 :(得分:0)

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

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

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

此外,Object.assign的工作方式......它创建了一个新的根对象,但它不能递归地工作。需要研究的东西:价值和参考类型之间的差异。值类型包括字符串,数字,布尔值,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不考虑数组(或对象)中的内容。