agile-ts / agile

🌌 Global State and Logic Library for JavaScript/Typescript applications

Home Page:https://agile-ts.org

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

State slice subscription for efficient subscriptions and updates.

laurencefass opened this issue Β· comments

πŸ†• Feature Request

If not already included integrate state slice subscription for efficient subscriptions and updates.

Does agilets manage subscriptions to state slices?

❓ Is your feature request related to a problem?

I created a sandbox here to try to express what I am trying to achieve. Results not as hoped for:
https://codesandbox.io/s/agilets-first-state-forked-d97

Lack of a state slice subscription mechanism would lead to inefficient updates a la React Context.

πŸ“„ Describe the solution you'd like

Redux provides very efficient state slice subscription through

πŸ“ƒ Describe alternatives you've considered

Redux does it but unfortunately still has compulsory Actions, Action Creators, Reducers.
Context also has a contrib packages that does slice subscription.

βž• Additional Notes

commented

Hi @laurencefass πŸ‘‹
Thanks for taking the time
creating the first Feature Request for AgileTs πŸŽ‰πŸ‘

Unfortunately, I couldn't exactly figure out what you mean,
but I give my best to answer your question. πŸ˜…

A small side note, your code sandbox link does not work.

In AgileTs, you have no single source of truth store object where all your States have to live.
Instead, AgileTs States are created individually and apart from each other.
Since all AgileTs States have an independent existence,
you only subscribe the needed individual States to the UI-Component,
instead of the whole store object (as common in redux);

const USER = createState({id: 1, name: 'jeff'});

// Component re-renders whenever the 'USER' State updates
const MyComponent = () => {
   const user = useAgile(USER);
   
   return <div>{user.name}</div>
}

However, if you want to subscribe only a specific part of the USER State to your Component,
you can use the useSelector() Hook

// Component re-renders whenever the property 'name' of the 'USER' State updates
const MyComponent = () => {
   const name = useSelector(USER, (user) => user.name);
   
   return <div>{name}</div>
}

or the useProxy() Hook.

// Component re-renders whenever the property 'name' of the 'USER' State updates
const MyComponent = () => {
   const user = useProxy(USER);
   
   return <div>{user.name}</div>
}

Sorry about the link still playing with it as I wasnt expecting such a speedy reply! I think you have answered the query perfectly but I cant find this in the documentation especially for the useProxy. Do you have a link?

thanks

useSelector works as expected but the Proxy subscriber is updates twice compared to once using the selector. https://codesandbox.io/s/agilets-proxy-kj7oo?file=/src/RandomComponent.js

shall i raise a separate issue for this?

another side note: useSelector makes this work like redux hook of same name without all the uncessary bootstrap code so this is a great alternative.

Are there any pros and cons of using useSelector vs useProxy?

commented

Sorry about the link still playing with it as I wasnt expecting such a speedy reply! I think you have answered the query perfectly but I cant find this in the documentation especially for the useProxy. Do you have a link?

thanks

Don't worry πŸ˜ƒ

Here is the documentation for the useProxy() Hook:
https://agile-ts.org/docs/react/hooks#useproxy


useSelector works as expected but the Proxy subscriber is updates twice compared to once using the selector. https://codesandbox.io/s/agilets-proxy-kj7oo?file=/src/RandomComponent.js

shall i raise a separate issue for this?

another side note: useSelector makes this work like redux hook of same name without all the uncessary bootstrap code so this is a great alternative.

Ok, I will check the useProxy() Hook for its correctness. Thanks for mentioning the potential issue ;D
If you have a reproducible example, feel free to open a separate issue ^^

I just checked out your codesandbox
and I noticed that you are trying to recreate the redux toolkit slice pattern.
However, this pattern isn't really applicable for AgileTs. In AgileTs, States are intended to be created separately and independent of each other.
Meaning, instead of having a main State (APP_STATE)
and creating slices based on this main State.

import { createState } from "@agile-ts/core";

export const APP_STATE = createState({
  counter1: { 
    value: 0
  },
  counter2: { 
    value: 0
  },
});
export const MY_SLICE1 = createState(APP_STATE.counter1);
export const MY_SLICE2 = createState(APP_STATE.counter2);

You should split up your main State (APP_STATE) and put its content into two separate States.
Something like that:

import { createState } from "@agile-ts/core";

export const COUNTER_1 = createState(0);
export const COUNTER_2 = createState(0);

I actually want a single state tree and a single source of truth to simplify debugging and state re-hydration (if needed). Really essential for complex state management. Your useSelector and useProxy fully support Redux style slices so I guess we have a choice with agilets

commented

Are there any pros and cons of using useSelector vs useProxy?

The main difference is that you have to manually select the value with the useSelector() hook.

// Re-renders when the 'name' property changes
const name = useSelector(USER, (user) => user.name);
console.log(name);

And with the useProxy() hook the selection happens based on the assessed properties.

// Re-renders when the 'name' property changes
const user = useProxy(USER);
console.log(user.name);
commented

I actually want a single state tree and a single source of truth to simplify debugging and state re-hydration (if needed). Really essential for complex state management. Your useSelector and useProxy fully support Redux style slices so I guess we have a choice with agilets

Yeah, I'm also a big fan of having a single source of truth store. πŸ˜ƒ

And if your approach (with the slice pattern) works for you. That's perfect πŸ‘.
I created AgileTs mainly to give people the flexibility
and possibility to decide for themselves how they want to manage their global States.
You have perfectly shown how various you can construct a store using AgileTs.
(Never thought that the slice pattern also works with AgileTs)

However, if you are interested in reading about my single source of truth store approach using AgileTs.
Check out the Style Guide documentation:
https://agile-ts.org/docs/style-guide

i have raised a separate useProxy issue.

Closing. This is a very simple, elegant state management solution. many thanks.

commented

Ok, thanks a lot for taking the time to test AgileTs. πŸ˜ƒ

If you have any further questions about AgileTs or programming in general,
feel free to join our Community Discord,
https://discord.gg/FTqeMNCxw7
or start a discussion here on github
https://github.com/agile-ts/agile/discussions

ThanksπŸ˜„