Make createMemo depend on unmentioned signal

I have a createMemo that depends on a list of objects
const items = createMemo(() => props.articles.map((article) => article.id));
const items = createMemo(() => props.articles.map((article) => article.id));
now, when I reorder that list of objects, the createMemo does not fire again, since I guess the content staid the same. Now I defined
const [reorderTag, setReorderTag] = createSignal(0);
const [reorderTag, setReorderTag] = createSignal(0);
that I increment each time I reorder the list. Short of
const items = createMemo(() => {
console.log(`reorderTag: ${reorderTag}`);
return props.articles.map((article) => article.id)
});
const items = createMemo(() => {
console.log(`reorderTag: ${reorderTag}`);
return props.articles.map((article) => article.id)
});
how do I make sure it refires? Making logic depend on console.log feels dirty.
15 Replies
mattasia
mattasia11mo ago
Where you set articles in your parent component ensure it's a new object i.e. setArticles([...reOrderedArticles]) You also don't need console.log You can also just discard instead const _ = reorderTag() But better yet use 'on' for explicit depend
Bersaelor
Bersaelor11mo ago
thanks, did the [...list]
mattasia
mattasia11mo ago
you also could potential change equals: to false on your signal - presuming you are actually setting it and not just mutating the article array without calling setSignal - this will run the effects even if the equality check is true
Bersaelor
Bersaelor11mo ago
yeah, but I don't want to run the risk of this evauluating unnecessarily
mattasia
mattasia11mo ago
with [...list] it will evaluate every single time you setArticles if [...list] is the argument, with equals: false it will evaluate every single time too, but without the allocation of a new list
bigmistqke
bigmistqke11mo ago
U can do createMemo(mapArray(articles, () => ...)) if you want to only run a function a single time per element. mapArray is what <For/> is using under the hood
NesCafe
NesCafe11mo ago
@bersaelor how come this does not work? can you check this playground code? https://playground.solidjs.com/anonymous/70394ed3-1bc5-4810-af96-3cb72ba6f396
Solid Playground
Quickly discover what the solid compiler will generate from your JSX template
NesCafe
NesCafe11mo ago
btw, memo-s are usually lazy. they will not call by themselves. only effects will
Bersaelor
Bersaelor11mo ago
hello, what doesn't work in your playground? When I open it I see the 1 and 2 and then 1s the 3
NesCafe
NesCafe11mo ago
I mean it is working. but in your first message you mentioned that in your app it was not updating memo correctly
Bersaelor
Bersaelor11mo ago
in the original question of this thread the problem came fromt he fact that I did reorder the elements in an array but not in fact change the array itself. using [...list] made sure my array is re-created, at the cost of allocating a new array your playground pushed a new item on the array. My problem was that I had an array where I moved item from position 1 to 7 but left the array object intact
NesCafe
NesCafe11mo ago
ah, that what I wanted - to know what change it was performed with items. maybe you can change the code in a playground to make it move 1st element to 7th index I must mention that there are two ways for modify array inside store. one is with produce helper. second is with setArticles setter by key
Bersaelor
Bersaelor11mo ago
what Mattasia said above also should be kept in mind:
with [...list] it will evaluate every single time you setArticles if [...list] is the argument, with equals: false it will evaluate every single time too, but without the allocation of a new list
In my case thats not a problem, to create new arrays when users move items around
Bersaelor
Bersaelor11mo ago
I used https://solid-dnd.com to let users reorder a list of items
Solid Drag & Drop
A lightweight, performant, extensible drag and drop toolkit for Solid.
NesCafe
NesCafe11mo ago
oh, good. will check it tomorrow. I'm from the phone already