NgRx v20 just dropped, and with it comes a shiny new feature: withLinkedState
.
Think of it like a buff for your SignalStore – it lets you create reactive, dependent state that automatically updates when its source changes. Less boilerplate, more focus on the fun stuff.
Imagine you’re building a little League of Legends dashboard. You’ve got a list of champions in your store, and you always want to keep track of the first champion in the list.
Without withLinkedState
, you’d probably write some extra logic in your component. With it, you can keep everything in the store:
const ChampionStore = signalStore(
withState({ champions: ['Nautilus', 'Blitzcrank', 'Leona'] }),
withLinkedState(({ champions }) => ({
currentChampion: () => champions()[0],
})),
withMethods((store) => ({
setChampions(champions: string[]): void {
patchState(store, { champions });
},
setCurrentChampion(champion: string): void {
patchState(store, { currentChampion: champion });
},
}))
);
That’s it, currentChampion
is just there, reactive and ready.
If the champions array changes, your “selected” champion updates instantly. Swap the list, and your new champion is auto-picked like magic. But if you want to take control, you can use patchState
to lock in your pick.
Ok, but what if you don’t just want the first champion, but want to stick to your main even if the champion list changes?
That’s where linkedSignal
comes in.
type Champion = { id: number; name: string };
const ChampionStore = signalStore(
withState({ champions: [] as Champion[] }),
withLinkedState(({ champions }) => ({
currentChampion: linkedSignal<Champion, Champion>({
source: champions,
computation: (newList, previous) => {
// Keep your old main if still in the new list
const currentChamp = newList.find((c) => c.id === previous?.value.id);
// Otherwise, default to the first champ
return currentChamp ?? newList[0];
},
}),
}))
);
So if you’re a Nautilus main (anchor’s down! ⚓) and the list updates, your store will keep you locked on him unless he’s removed. If he’s gone, you’ll default to the first champ in line.
withLinkedState
feels like unlocking a new rune: less effort, more power, and smoother gameplay when it comes to managing state. It’s a neat addition that makes your store logic more intuitive and future-proof.
Top comments (0)