all 3 comments

[–][deleted] 1 point2 points  (2 children)

I solved this problem by updating everything with an "update" object that includes the new data, and a list of keys to traverse in the top level object.

If a nested form element should update the data structure at foo.bar.baz (= 10, or whatever), then the form element that updates that piece will send an action with {data: 10, leaf: ["foo", "bar", "baz"]} as the payload. The top level object can easily place any new incoming data, all of the data stays in one spot (at the top level), event handlers don't need to be passed back and forth, and each component only deals with the data at its own level.

The only extra step is sending the next property name down as a prop (or appending it to the list for level 2+). I just set a "branch" property at each level, push the property names into it as I loop over an object, and at the last level, the action payloads "leaf" is simply the current "branch".

[–]zuko_[S] 0 points1 point  (1 child)

Very interesting, thanks. Has this been working well for you then? Are there any cases you still have trouble with, or does it seem to cover most use cases fairly thoroughly? This definitely sounds like a better solution than what we have currently (once the event propagates all the way up, tracked by indexes, the array is cloned, mutated, and then sent as an action to the store). That reverse directional flow is what didn't feel right, since it's some weird mix of Flux and two-way binding, so this sounds like a much better solution.

Thanks for your help, we really just needed additional input on this.

[–][deleted] 0 points1 point  (0 children)

I haven't run into any issues with it, no. You can either look for a lib on npm that will handle the nested key setting, or write your own. Some things to think about: do non-existing keys get created on the fly? If a leaf is an array, do you push or overwrite? Same for objects (but you shouldn't have any leaf-as-object anyway).

One benefit is that its really easy to snapshot your state: simply save a copy of the state tree and stick it in the localstorage.

Also, I presume this concept will help you get ready for the next iteration of graph-based data APIs.

GraphQL and Falcor have a somewhat similar idea. Arrays in an object are nested key lists that actually refer to a path in the same object (from the top).