adrien
adrien
SSolidJS
Created by adrien on 12/6/2023 in #support
Lazy-initialized createMemo's updating once, but not again
Oh man this is awesome, thank you for explaining and digging that up! I'm gonna take some time tomorrow to try to digest this. Thanks also for pointing me to createLazyMemo and the Solid Primitives project, didn't know about that!!
29 replies
SSolidJS
Created by adrien on 12/6/2023 in #support
Lazy-initialized createMemo's updating once, but not again
Here's a simplified version using 2 signals instead of a store: https://playground.solidjs.com/anonymous/7ff5df2b-02a5-4385-a669-d4bc44d2c99f Same issue as before. And also something interesting (happens in both versions), for B, the bMemo and bLazyMemo effects seem to alternate which order they get triggered in on each change. Not sure why, but that could point toward the reason for this strange behavior.
29 replies
SSolidJS
Created by adrien on 12/6/2023 in #support
Lazy-initialized createMemo's updating once, but not again
All right I've got another one to throw at this quandary! https://playground.solidjs.com/anonymous/13b9938d-f7b5-4227-9b58-f32c58d0c272 I set up A and B the exact same way, and log the result of the lazy memo for each in a createEffect. The only difference is I also render the result of the lazy memo of B in the DOM. The result is that the effect for A only triggers on the first update, and not on any subsequent update. But the effect for B triggers on every update. My expectation is that A's effect should also trigger on each update, so I'm wondering why that's not happening??
29 replies
SSolidJS
Created by adrien on 12/6/2023 in #support
Lazy-initialized createMemo's updating once, but not again
Ok I LOVE that that works, but I can't comprehend how it works....?? I mean it's literally doing the same thing, just moving the unwrapping up to the caller. Right?? What am I missing here?
29 replies
SSolidJS
Created by adrien on 12/6/2023 in #support
Lazy-initialized createMemo's updating once, but not again
WHOA! So just returning the accessor instead of the unwrapped value from getFibForCounter, right??
29 replies
SSolidJS
Created by adrien on 12/6/2023 in #support
Lazy-initialized createMemo's updating once, but not again
So I wonder, is there something incorrect about using createMemo inside a reactive frame (I don't know what to call this)? Like it seems like the memo works correctly when initialized in the Component function (during setup as opposed to during render I guess?). But is acting strange when the memo is initialized in a reactive render? But if that's the case, I would expect Solid to yell at me for doing that, the same way it yells at me for creating computations outside of a render context. Should Solid be able to recognize like "hey, we're in a context where using createMemo doesn't work, here's a warning", the same way it can when you're not in the proper context?
29 replies
SSolidJS
Created by adrien on 12/6/2023 in #support
Lazy-initialized createMemo's updating once, but not again
Oooh ok so going off of my first code sample, here is a slight alteration of it where I call getFibForCounter("a") in the Component function for the "a" counter, but not the "b" counter. So this initializes the memo-function for "a" before the return statement, but not for "b". And now, it works for the "a" counter, but not for "b". https://playground.solidjs.com/anonymous/8d6d68ec-60b5-4ca5-b4a3-7081d33badba
29 replies
SSolidJS
Created by adrien on 12/6/2023 in #support
Lazy-initialized createMemo's updating once, but not again
And specifically I'd like to understand why the original code appears to work for initial state AND 1st update, but not any subsequent updates. I could rationalize it away if it didn't work for any updates, but it just seems odd that it stop after the 1st update.
29 replies
SSolidJS
Created by adrien on 12/6/2023 in #support
Lazy-initialized createMemo's updating once, but not again
Thanks for looking into this @bigmistqke !! I'll try out your alternate patterns for now. But I am still curious about why this other pattern isn't working. You're saying that the memo-function is recreated each time getFibForCounter is called, but I don't believe that's true. This is how I'm interpreting what's going on: - getFibForCounter("a") 1st call: the memo-function is created and stored in fibByCounterKey["a"] because fibByCounterKey["a"] isn't defined yet. - getFibForCounter("a") 2nd call: the memo-function that was created in 1st step is retrieved from fibByCounterKey["a"] because fibByCounterKey["a"] is defined now. Am I missing something? Thanks for helping me understand! Would really love to get why this pattern isn't working! I guess I'm really wishing there was something like createMemo but parameterized. Like, in the way I could make a parameterized derived signal like this (I know that's technically not an Accessor, but it still works right):
const doubleCounter = (key: string) => counters[key] * 2;
const doubleCounter = (key: string) => counters[key] * 2;
I wish I could make a memoized parameterized derived signal, where it would key its memoized values by the parameters.
29 replies
SSolidJS
Created by adrien on 12/6/2023 in #support
Lazy-initialized createMemo's updating once, but not again
Sample code:
import { Accessor, Component, For, createMemo } from "solid-js";
import { createStore } from "solid-js/store";

function fibonacci(num: number): number {
if (num <= 1) return 1;

return fibonacci(num - 1) + fibonacci(num - 2);
}

const MemoSample: Component = () => {
const [counts, setCounts] = createStore<{ [key: string]: number }>({
a: 3,
b: 5,
});

const fibByCounterKey: { [key: string]: Accessor<number> } = {};

const getFibForCounter = (key: string): number => {
let fibForCounter = fibByCounterKey[key];

if (!fibForCounter) {
fibForCounter = fibByCounterKey[key] = createMemo(() => {
const count = counts[key];

if (count === undefined) {
throw new Error();
}

return fibonacci(count);
});
}

return fibForCounter();
};

return (
<For each={Object.keys(counts)}>
{(key) => (
<>
<button onClick={() => setCounts(key, (v) => v + 1)}>
Counter {key}: {counts[key]}
</button>
<div>
{getFibForCounter(key)} {getFibForCounter(key)}&nbsp;
{getFibForCounter(key)} {getFibForCounter(key)}&nbsp;
{getFibForCounter(key)} {getFibForCounter(key)}&nbsp;
{getFibForCounter(key)} {getFibForCounter(key)}&nbsp;
</div>
</>
)}
</For>
);
};

export default MemoSample;
import { Accessor, Component, For, createMemo } from "solid-js";
import { createStore } from "solid-js/store";

function fibonacci(num: number): number {
if (num <= 1) return 1;

return fibonacci(num - 1) + fibonacci(num - 2);
}

const MemoSample: Component = () => {
const [counts, setCounts] = createStore<{ [key: string]: number }>({
a: 3,
b: 5,
});

const fibByCounterKey: { [key: string]: Accessor<number> } = {};

const getFibForCounter = (key: string): number => {
let fibForCounter = fibByCounterKey[key];

if (!fibForCounter) {
fibForCounter = fibByCounterKey[key] = createMemo(() => {
const count = counts[key];

if (count === undefined) {
throw new Error();
}

return fibonacci(count);
});
}

return fibForCounter();
};

return (
<For each={Object.keys(counts)}>
{(key) => (
<>
<button onClick={() => setCounts(key, (v) => v + 1)}>
Counter {key}: {counts[key]}
</button>
<div>
{getFibForCounter(key)} {getFibForCounter(key)}&nbsp;
{getFibForCounter(key)} {getFibForCounter(key)}&nbsp;
{getFibForCounter(key)} {getFibForCounter(key)}&nbsp;
{getFibForCounter(key)} {getFibForCounter(key)}&nbsp;
</div>
</>
)}
</For>
);
};

export default MemoSample;
29 replies
SSolidJS
Created by adrien on 2/21/2023 in #support
How to untrack() or on() a props value?
for sure, i'm only thinking about for custom components that can handle functions for that stuff
16 replies
SSolidJS
Created by adrien on 2/21/2023 in #support
How to untrack() or on() a props value?
Oh nice one-liner!
16 replies
SSolidJS
Created by adrien on 2/21/2023 in #support
How to untrack() or on() a props value?
For reference for anyone else looking at this, this is also a good discussion on this topic https://github.com/solidjs/solid/discussions/749
16 replies
SSolidJS
Created by adrien on 2/21/2023 in #support
How to untrack() or on() a props value?
ah ok! i was actually toying around with passing Accessors instead of values as props, and i think it makes more sense in my mind. I understand why it was built this way, but it does seem a little weird that by default reactive values are unwrapped then wrapped again when passed down through props, and then you can't access the wrapper in the child component, you're stuck calling the getter. I'll try passing functions instead and see if that ends up making more sense. Thanks!
16 replies
SSolidJS
Created by adrien on 2/21/2023 in #support
How to untrack() or on() a props value?
Thanks @fabiospampinato ! Would you consider needing to untrack a props value a code smell, signifying I might be thinking about stuff the wrong way? Or is wanting to untrack a props value a legit thing that should/could hapen
16 replies