S
SolidJS5d ago
dtnc

Would this break reactivity?

I'm new to signals. The solidstart tutorial mentioned that destructuring may break reactivity in components. I don't fully understand that just yet and wonder if that means the following hook would break reactivity. This is a convenience hook I'm writing to simplify usage of the better-auth useSession hook. If it can potentially break reactivty, how would you suggest accomplishing the goal of unpacking the data field into user and session?
export function useUserSession() {
const sData = useSession()

const unpacked = () => {
const { data, ...statusProps } = sData()

return {
user: data?.user,
session: data?.session,
isAuthenticated: data?.session.token,
...statusProps
}
}
return unpacked
}
export function useUserSession() {
const sData = useSession()

const unpacked = () => {
const { data, ...statusProps } = sData()

return {
user: data?.user,
session: data?.session,
isAuthenticated: data?.session.token,
...statusProps
}
}
return unpacked
}
3 Replies
foolswisdom
foolswisdom5d ago
This is fine, so long as unpacked is called in a tracking context The destructuring problem is an issue (=doesn't track) when it's done outside a tracking context, because the track occurs on property access (unless it's on function call, as when calling signals), and that's occurring outside the tracking context
peerreynders
peerreynders4d ago
Ripping apart an object and reassembling another just to access a single property isn't great form. If you require the “object ergonomics” then put in the work to create a reactive object with getters. As such it's the idiom that props use and is practised frequently.
export function useUserSession() {
return {
get user() {
return useSession()?.user;
},
get session() {
return useSession()?.session;
},
get isAuthenticated() {
return useSession()?.session.token;
},
// … getters for relevant statusProps …
};
}
export function useUserSession() {
return {
get user() {
return useSession()?.user;
},
get session() {
return useSession()?.session;
},
get isAuthenticated() {
return useSession()?.session.token;
},
// … getters for relevant statusProps …
};
}
Personally I start with utility functions and often don't get to the point where I have need for the object as a bag of methods semantics
function userFromSession() {
return useSession()?.user;
}

function sessionFromSession() {
return useSession()?.session;
}

function isAuthenticated() {
return Boolean(useSession()?.session.token);
}
function userFromSession() {
return useSession()?.user;
}

function sessionFromSession() {
return useSession()?.session;
}

function isAuthenticated() {
return Boolean(useSession()?.session.token);
}
All these really are, are derived signals. Alternately if your pattern of usage is to capture the session result inside memo/effect functions to be (synchronously) shared throughout their logic then use:
function userFrom(s: ReturnType<typeof useSession>) {
return s?.user;
}

function sessionFrom(s: ReturnType<typeof useSession>) {
return s?.session;
}

function isAuthenticated(s: ReturnType<typeof useSession>) {
return Boolean(s?.session.token);
}
function userFrom(s: ReturnType<typeof useSession>) {
return s?.user;
}

function sessionFrom(s: ReturnType<typeof useSession>) {
return s?.session;
}

function isAuthenticated(s: ReturnType<typeof useSession>) {
return Boolean(s?.session.token);
}
dtnc
dtncOP4d ago
thank you

Did you find this page helpful?