-
Notifications
You must be signed in to change notification settings - Fork 109
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Document the stores registry pattern #299
Comments
Hi, thanks for the question. Setting new property to a value is equivalent
to adding a property to an object. And so it means the entire object is
changed, so all the nested properties which are used trigger rerender...
Unfortunately there is no easy way around this.
One option could be to track if enumeration of keys or values of an object
happened during render and rerender only in this case. I will keep the
ticket open as a reminder to consider the improvement, but i am afraid it
is not going to be easy or quick. As a workaround consider to assign all
properties to undefined on the app start.
…On Thu, 23 Jun 2022, 22:07 Valery Buchinsky, ***@***.***> wrote:
Hi @avkonst <https://github.com/avkonst>
Really hate when people start their dumb questions with "first of all
thank you for the great lib", but... it's true, so
First of all thank you for the great lib!
This is not a bug report but rather a question. "Is it supposed to work
this way?"
I have a Map-like state that is initialized as an empty object {}.
Keys are then added to it. state['new-key-1'].set('value');
Whenever that set above is done, all usages of state get rerendered.
I have created a simple repro here
https://codepen.io/vbuch/pen/poaXYgZ?editors=0011 where you can observe
the above.
Accessor1 is getting rerendered/called on every hit to the "Add more"
button.
Accessor2 is not.
I would imagine that the access that Accessor1 does won't be tracked as
usage hence won't force a rerender, but... I may be missing something.
Thank you in advance!
—
Reply to this email directly, view it on GitHub
<#299>, or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AA6JSVJKHOJBA4D3OZBDF33VQQZMNANCNFSM5ZTYYDYQ>
.
You are receiving this because you were mentioned.Message ID:
***@***.***>
|
Thank you for the quick reply! It is indeed a hard one, I understand. Here is a usecase:
I have thought of a possible approach that will not force rerenders but that requires duplicating the selected item in a separate state/member of state. That becomes tricky with the third point above. I've experimented with an array, but then I need to access repo.keys whenever I want to find an item, therefore I will again force render because I'm accessing keys. If I go the state = {repo: {}, selected: {}} and then add to both, I have to make sure I keep both instances repo[id] and selected in sync and that is again... tricky. I'm out of ideas, so will be greatful if you have some. Edit: I think I figured out a solution. I am asking hookstate to be a repository, while that's not what it is. I would rather have a repo (think JS Map) that holds many State objects. Then a new item will come in that repo as map.set('new-item', createState(item)) and we're back to simple basics. Map does what it's supposed to do and hookstate does what it does great. I'm leaving the above part of my reply for history and resoning. Thank you again! Edit 2: This appears to be harder than I imagined even this way. Edit 3: Here is a repro of the above mentioned approach: https://codepen.io/vbuch/pen/JjpQzeK?editors=0011 |
Thanks, very nice. yes, I used the repository of states in my projects. This approach works. |
Keep it open to update the docs how to create a repository of states. |
Also reminder from the above: "track if enumeration of keys or values of an object happened during render and rerender only in this case" |
Also, somewhat duplicate of #51 |
I think another term was already used somewhere in the docs for that. Let me fetch it. Wasn't "registry", nor "repository", neither "dictionary". Edit: Found it. This is referred to as "catalog of dynamically created and destroyed global states" in createState's lines. |
@avkonst I think I'm also running into this issue. Data structure is like this: const stateMap = hookstate({} as {
[id:number]: Array<Item>|null
}) when I do I don't know that a non-tracked registry pattern works for me, since I need to be able to react to the registry itself having items added and removed. |
@speigg , the way I went around that is: |
@speigg what do you mean by "it causes other nested states to invalidate for other ids" ? |
@vbuch yes, I'm landing on a very similar pattern. something like:
This way, each item in the
@avkonst It's a relief to know that's the intention
Hard to tell exactly what the cause is, but I am generally seeing undesired/unnecessary component invalidations and state proxies being updated. I might have to create an isolated test case to zero in on the exact mechanism that is causing this behavior, but the only other thing would be items being removed/added from a top level hookstate record, i.e., |
@speigg adding a new key to There used to be a table that showed updating what causes a render in where. I cannot seem to find that in the docs @avkonst Edit: Here it is in version 3. Did a lot of this change? |
Hi @avkonst and contributors,
Really hate when people start their silly questions with "first of all thank you for the great lib", but... it's true, so
First of all thank you for the great lib!
This is not a bug report but rather a (silly?) question. "Is it supposed to work this way?"
I have a Map-like state that is initialized as an empty object {}.
Keys are then added to it. state['new-key-1'].set('value');
Whenever that set above is done, all usages of state get rerendered.
I have created a simple repro here https://codepen.io/vbuch/pen/poaXYgZ?editors=0011 where you can observe the above.
Accessor1 is getting rerendered/called on every hit to the "Add more" button.
Accessor2 is not.
I would imagine that the access that Accessor1 does won't be tracked as usage hence won't force a rerender, but... I may be missing something.
Thank you in advance!
The text was updated successfully, but these errors were encountered: