S
SolidJS•2y ago
Casacobra

Reactivity when passing props down not reactive on nested component

Hi guys and girls, I'm currently struggling with reactivity. Here's a look at the code: ParentComponent.tsx

export default function ParentComponent(props) {
// signal stuff
const [level, setLevel] = createSignal(...)
// create effect stuff

return level()?.placements.map((placement) => {
const [x, y] = placement.displayXY()

return (
<div
style={{
position: 'absolute',
transform: `translate3d(${x}px, ${y}px, 0px`,
}
}>
{placement.renderComponent()}
</div>
)
}
}

export default function ParentComponent(props) {
// signal stuff
const [level, setLevel] = createSignal(...)
// create effect stuff

return level()?.placements.map((placement) => {
const [x, y] = placement.displayXY()

return (
<div
style={{
position: 'absolute',
transform: `translate3d(${x}px, ${y}px, 0px`,
}
}>
{placement.renderComponent()}
</div>
)
}
}
If I add this in the parent to test, everything works correctly and properties are reactive. However, when I move this into another component ChildComponent.tsx I loose reactivity and instead get static values... ParentComponent.tsx:
export default function ParentComponent(props) {
// signal stuff
const [level, setLevel] = createSignal(...)

// create effect stuff

return(
<ChildComponent level={level()} />
)
}
export default function ParentComponent(props) {
// signal stuff
const [level, setLevel] = createSignal(...)

// create effect stuff

return(
<ChildComponent level={level()} />
)
}
ChildComponent.tsx:
export default function ChildComponent(props) {
return (
<For each={props.level.placements}>
{(placement) => {
const [x, y] = placement.displayXY()

return (
<div
style={{
position: 'absolute',
transform: `translate3d(${x}px, ${y}px, 0)`,
}}
>
{placement.renderComponent()}
</div>
)
}}
</For>
)
}
export default function ChildComponent(props) {
return (
<For each={props.level.placements}>
{(placement) => {
const [x, y] = placement.displayXY()

return (
<div
style={{
position: 'absolute',
transform: `translate3d(${x}px, ${y}px, 0)`,
}}
>
{placement.renderComponent()}
</div>
)
}}
</For>
)
}
Any help would be greatly appreciated, thanks in advance!
10 Replies
foolswisdom
foolswisdom•2y ago
Quick sanity check - the code as two components and one component are me the same. Namely, one uses the map method, and the other uses For (and also doesn't use optional chaining, so level may be undefined?) Can you confirm that it behaves differently even when the two version are the same?
Casacobra
CasacobraOP•2y ago
@foolswisdom If I do it in the root component, ParentComponent as a map it works and reactivity works, the minute i move it to a child component is when it does not become reactive when I use <For> or map... It's so strange..
foolswisdom
foolswisdom•2y ago
So, when you say that it's not reactive, does that mean the x and y properties don't update, or that nothing happens when you add items
Casacobra
CasacobraOP•2y ago
@foolswisdom Exactly, x and y do not update for some bizarre reason But if i move the code to the root component, it's reactive, with the exception of using .map
foolswisdom
foolswisdom•2y ago
It looks like x and y aren't signals, ah the only way for them to update would be to rerun the whole block. Which would require the display method to access reactive values. So does it access signals / stores? (i don't know why this would have been working in a single component 🤷)
Casacobra
CasacobraOP•2y ago
It accesses one signal called [level, setLevel] Please bare in mind, which I forgot to say. level is constantly looping as in using requestAnimationFrame...
high1
high1•2y ago
I think that you should just wrap the result in a function const placement = () => placement.displayXY() And then access it like placement().x and placement().y
Casacobra
CasacobraOP•2y ago
Yeah I tried this too and for some bizarre reason it isn’t playing nicely! Thanks for the response. I’ll continue debugging and see where I get to!
REEEEE
REEEEE•2y ago
You could perhaps use a store? It could be the values for level are updated maybe?
high1
high1•2y ago
The function approach should work. Solid is not detecting that something has changed, so you need to add a hint to make this reactive. Or you could use a store, which also must work.
Want results from more Discord servers?
Add your server