How to react to length of store array?

I have a store representing an array:
const [pools, setPools] = createStore<Pool[]>([])
const [pools, setPools] = createStore<Pool[]>([])
Elsewhere I render a list based on that array:
<Column class="px-2">
<Row>
<For each={pools}>{(p, i) => <PoolView index={i()} />}</For>
<CreatePoolViewButton index={pools.length} />
</Row>
</Column>
<Column class="px-2">
<Row>
<For each={pools}>{(p, i) => <PoolView index={i()} />}</For>
<CreatePoolViewButton index={pools.length} />
</Row>
</Column>
pools.length is always 0, even when I successfully add an element to the pool store. How do I get the value reactively?
10 Replies
deluksic
deluksic4mo ago
How did you add the element?
Ghirigoro
Ghirigoro4mo ago
const addPool = () => {
setPools([...pools, { dice: 1, results: [] }])
}
const addPool = () => {
setPools([...pools, { dice: 1, results: [] }])
}
deluksic
deluksic4mo ago
Hmm, that should work, but can you try with setPools(produce((array)=>{array.push(...)})) Or maybe CreatePoolViewButton destructures somewhere so you lose reactivity?
Ghirigoro
Ghirigoro4mo ago
Nope, no destructuring that I can see and:
const addPool = () => {
// setPools([...pools, { dice: 1, results: [] }])
setPools(
produce(array => {
array.push({ dice: 1, results: [] })
})
)
}
const addPool = () => {
// setPools([...pools, { dice: 1, results: [] }])
setPools(
produce(array => {
array.push({ dice: 1, results: [] })
})
)
}
has the same effect
deluksic
deluksic4mo ago
So a createEffect console.log also doesnt respond to pools.length?
Ghirigoro
Ghirigoro4mo ago
No it does... Here's the code for the button where I consitstently get an index value of 0:
const CreatePoolViewButton: Component<{ index: number }> = ({ index }) => {
return (
<button
class="flex items-center justify-center"
onClick={() => {
console.log("click", index)
// if the pool at the index is not defined, add a new pool
if (pools[index] === undefined) addPool()
else removePool(index)
}}
>
<svg
class="w-4 h-4 text-light stroke-light"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="1"
stroke-linecap="round"
stroke-linejoin="round"
>
<circle cx="12" cy="12" r="11"></circle>
<line
style={{
transition: "transform 0.3s",
"transform-origin": "center",
transform: `rotateZ(${pools[index] !== undefined ? "90" : "0"}deg)`,
}}
x1="12"
y1="8"
x2="12"
y2="16"
></line>
<line x1="8" y1="12" x2="16" y2="12"></line>
</svg>
</button>
)
}
const CreatePoolViewButton: Component<{ index: number }> = ({ index }) => {
return (
<button
class="flex items-center justify-center"
onClick={() => {
console.log("click", index)
// if the pool at the index is not defined, add a new pool
if (pools[index] === undefined) addPool()
else removePool(index)
}}
>
<svg
class="w-4 h-4 text-light stroke-light"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="1"
stroke-linecap="round"
stroke-linejoin="round"
>
<circle cx="12" cy="12" r="11"></circle>
<line
style={{
transition: "transform 0.3s",
"transform-origin": "center",
transform: `rotateZ(${pools[index] !== undefined ? "90" : "0"}deg)`,
}}
x1="12"
y1="8"
x2="12"
y2="16"
></line>
<line x1="8" y1="12" x2="16" y2="12"></line>
</svg>
</button>
)
}
If I add this at the top of the button component:
createEffect(() => {
console.log("index", index)
})
createEffect(() => {
console.log("index", index)
})
it always comes out 0
deluksic
deluksic4mo ago
Yeah, you destruct props which is a no no
Ghirigoro
Ghirigoro4mo ago
Oh crap! So sorry
deluksic
deluksic4mo ago
No worries, you can look into eslint plugin to help catch these
Ghirigoro
Ghirigoro4mo ago
It's just so ingrained in me I literally don't see it any more when it's in the function parameters Thanks for your help and sorry to waste your time