-
-
Notifications
You must be signed in to change notification settings - Fork 649
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
[Question]: What is the most performant way for dynamically adding atoms or focus atoms for a large tree? #447
Comments
Assuming you don't need any serialization, making an atom for the object with the id is a primary approach, and probably performant.
So, basically this. But, nesting atoms in a tree might not be handy in your use case. (Because, you can only add an item to its parent.) Creating id tree and using atomFamily can be another option. We don't have any examples with this approach, though. Some previous discussion: #255 |
I'm working on a project with a pretty similar use case. I do have the need to serialize it though. What I'm currently doing is by creating the So every time there's a change of order or add/remove of component, I manually update the map. I'm not sure if it's an ideal way of doing it, maintaining the map is a bit cumbersome (I currently rebuild it every time there's such a change) but otherwise it works alright so far. |
It sounds like there could be a better way. Can either/both of you create a smaller example to play/discuss with? btw, serialization only might not a big issue, de-serialization is the hard part. (This would become a good example in docs.) |
@dai-shi With this implementation it barely works, and de-serialization would be super easy. But I still feel there are a lot of things can be improved, which I'm having a bit difficulty finding out how. I tried to use focusAtom and atomFamily to simplify it a bit, but there are a few errors and I have no idea how to fix so I deleted the code. Also, I kind of feel like it'd be very convinient if there is a getter atom which can take an extra argument as input. For example |
Thanks for the example! It's small enough to understand the structure. First of all, we have two basic approaches.
what you are doing is 1 and it's fast for (de)serializing, but updating can be slower (still enough efficient). On the other hand, 2 is faster for updating, but slower for (de)serializing. I've only tried a simple one (todos app) for 2. If you go with 2, it will be the entire rewrite. The biggest question in your current approach is whether you need to keep updating After that, only remaining thing is to utilize focusAtom and splitAtom to render elementsAtom. At that point, I'm not sure if idToPathMap is necessary, as you don't need |
atomFamily is another option, and that might fit with
Isn't it
Yes, we'd need |
@dai-shi For my use case I need to seralize it every time I change it, for keeping a history so it can undo / redo changes. The reason why I created an idToPath map instead of a derived getter atom is that I think it doesn't always need to be updated if the modification is just the payload which happens very fraquently, instead of adding / removing / reordering elements which in my case are less fraquent. But still, I originally thought it's better to just update the changes, instead of traversing the entire tree again. It takes some time to write the logic though. And I'm always open for improvements. I'll try to think a bit more about it and probably improve the code. |
I see.
That makes sense. We could try optimization later though and there might be some other ways to optimize. |
That'll be even better. It's just that I haven't found a way to do it with my limited experince of this module. But I'm happy to see better implementations |
Have you seen |
Yes, I've noticed that. So let's say there is a feature that I'd like to select a component and change the order of it (move up and down relative to its siblings), or set a different parent component, or to delete some of the selected components. Is it doable using |
Yes, it should! It's a relatively new function, so you might expect some bugs, but yeah that's the goal. For reordering, your |
I was trying to do reorder using |
Oh, right. Yeah, I mean you reorder the original array atom and splitAtom works well with keyExtractor. To be honest, I haven't tried it. So, I'm happy to help your example. |
Hi @dai-shi , could you please shed some light on how to implement similar logic with |
Sure. So, I made this example. |
Sorry if my comment is not appropriate to make here but after doing a bit of experiments, I found that
|
Yeah, we need more best practices and some utils to deal with tree structure effectively. For now, we are still working on a flat list and |
This was actually my bad. I forgot https://codesandbox.io/s/react-typescript-forked-5cnu1?file=/src/App.tsx |
This has been a great discussion. We've fixed some bugs. Closing this now, and for further discussions, please open a new issue/discussion. |
Hi folks,
First of all, great work done with Jotai. Good documentation too.
I have a use-case where i am require to maintain a component tree and its styles, which are to be rendered on a page. Each of this component's style can be modified. At the moment i use a single
useState
to update the tree whenever a component style is updated. I feel Jotai can help optimise for performance here as this tree can grow quite large.Example tree:
My question is what is the best way to add state to this given we have dynamic tree. I saw an example here which deals with a similar problem using
focusAtoms
https://github.com/pmndrs/jotai/blob/master/docs/advanced-recipes/large-objects.mdHowever, in the above tree the only unique field i have is an id, which is auto generated whenever a component is added to the tree. I can probably use that to dynamically create an atom but issue with that approach is, how do i update the whole component tree itself.
Would appreciate some help/suggestions here on how to best use Jotai for my example.
Cheers :)
The text was updated successfully, but these errors were encountered: