JavaScript的sort方法是否修改原数组?React调用sort后数组未更新
问题解答
1. sort方法的行为
JavaScript的Array.prototype.sort()是原地排序方法,既会直接修改调用它的原数组本身,同时也会将修改后的原数组作为返回值返回,并不会生成新的数组对象。
2. 代码不生效的原因
你代码中的let sortedInvoices = this.state.invoiceList只是将invoiceList的数组引用赋值给了新变量sortedInvoices,二者始终指向内存中的同一个数组对象。你对sortedInvoices调用sort原地修改后,它和this.state.invoiceList还是同一个引用,所以===判断会返回matched。
而React的state更新默认做浅比较,当你给setState传入的数组和原state里的数组是同一个引用时,React会判定state没有发生变化,因此不会触发组件重渲染,你也就看不到排序后的效果。
3. 修复方案
在排序前先对原数组做浅拷贝,生成新的数组对象,再对拷贝后的数组排序,这样就能给setState传入新的引用触发重渲染。
浅拷贝数组可以用展开运算符[...arr]或者arr.slice()方法,修正后的代码如下:
function setInvoiceSortField(field) { console.log(field); if (field !== null) { // 先浅拷贝原数组,生成新的引用 let sortedInvoices = [...this.state.invoiceList]; sortedInvoices.sort((a, b) => { console.log(`a ${a[field]}`); console.log(`b ${b[field]}`); if (a[field] < b[field]) { return -1; } if (a[field] > b[field]) { return 1; } return 0; }); this.setState({ invoiceList: sortedInvoices }); } }
补充说明
如果你的数组元素是复杂对象,且排序时需要处理嵌套属性、数值/字符串类型排序不一致的问题(比如字符串形式的数字按字典序排序和数值排序结果不同),可以再对应调整sort的比较函数逻辑,上述修改已经可以解决你当前遇到的数组无变化、页面不更新的问题。
内容的提问来源于stack exchange,提问作者Randy
相关产品推荐
相关产品推荐

