Svelte:传递声明的函数时,反应式声明不起作用



问题

状态变量发生变化时,我创建了一个反应参数来对数组进行排序。如果我直接将sort函数声明为回调,但如果我传递一个已经声明的函数,它就不会起作用。

代码

因此,这是不起作用的代码:

const sortSongs = (a, b) => {
const [option, direction] = sortOption.split("-");
const itemA = a[option == "Song" ? "title" : "artist"].toLowerCase();
const itemB = b[option == "Song" ? "title" : "artist"].toLowerCase();
if (itemA < itemB) {
return direction == "up" ? 1 : -1;
}
if (itemA > itemB) {
return direction == "up" ? -1 : 1;
}
return 0;
};
$: filteredSongs =
lessons
?.sort(sortSongs)
.filter(lesson => lesson.title?.toLowerCase().includes(value)) || [];

这个人确实工作:

$: filteredSongs =
lessons
?.sort((a, b) => {
const [option, direction] = sortOption.split("-");
const itemA = a[option == "Song" ? "title" : "artist"].toLowerCase();
const itemB = b[option == "Song" ? "title" : "artist"].toLowerCase();
if (itemA < itemB) {
return direction == "up" ? 1 : -1;
}
if (itemA > itemB) {
return direction == "up" ? -1 : 1;
}
return 0;
})
.filter(lesson => lesson.title?.toLowerCase().includes(value)) || [];

困惑

那么两个都不应该工作吗?为什么我在哪里声明函数会有区别?这里有一个REPL,可以看到这一点。红色歌曲得到了无效代码,而绿色歌曲得到了有效代码。

您希望$: filteredSongssortOption更改时重新评估,但当您传递函数引用.sort(sortSongs)时,sortOption"隐藏"在函数内部,不再与反应语句直接相关。第二段的文档中提到了这一点

只有直接出现在$:块中的值才会成为反应语句的依赖项

一个快速而肮脏的解决方案是将sortOption作为参数传递

?.sort(sortSongs, sortOption)

.sort()只期望比较函数作为参数,因此sortOption将被忽略,但由于在$:块内再次出现,因此它也是一个依赖项

如果不使用"冗余"参数调用.sort(),这将是一个更清晰的替代方案

let lessons = [];
...
const sortSongs = (songs, sortOption) => {
return songs.sort((a,b) => {
const [option, direction] = sortOption.split("-");
const itemA = a[option == "Song" ? "title" : "artist"].toLowerCase();
const itemB = b[option == "Song" ? "title" : "artist"].toLowerCase();
if (itemA < itemB) {
return direction == "up" ? 1 : -1;
}
if (itemA > itemB) {
return direction == "up" ? -1 : 1;
}
return 0;
})     
};
$: filteredSongs =
sortSongs(lessons, sortOption)
.filter(lesson => lesson.title?.toLowerCase().includes(value));

最新更新