State Anchoring

GState use the pattern extensively to solve many state management problems. Basically, the method is make object reference to well known path.

const value = { a: "a" };
state.set({
   well_known_path: value // reference the value to well known path 
   a: {
      b:{
         c: value // original state 
      }
   }
});
// Next time we clear original state
state.set({ a: undefined });
// Value still survive at well_known_path
state.get("well_known_path.a") => "a"
// re-link to original or link to other state
const dummy = {};
state.set({ 
   well_know_path: dummy,
   a: {
      b: {
         c: dummy // re-link 
      }
   },
   other: dummy // link to other
});
state.get("a.b.c.a") => "a"
state.get("other") => "a"

State anchoring use cases included:

  • Cache long lived states.
  • State relationship.
  • Communication between components.

Cache long lived states

GState's states have same power as native JS objects. Whenever you want to cache a long lived data, you could add the data reference into a global JS object.

const global_cache = {};

function fetch_data(){
    ...
    global_cache[data_id] = data;
    return global_cache[data_id];
}

function get_data(){
    if (global_cache[data_id]){
        return global_cache[data_id];
    }
    ...
}

With gstate, you only make reference to a well known path. Then you could retrieve or re-link the cache data from the well known path.

function fetch_data(){
    ...
    state.set({
        global_cache: {
            [data_id]: data // anchoring to cache
        },
        views:{
            view_a: {
                data: data // original state path
            }
        }
    })
}

function get_data(){
    ...
    state.get(["global_cache", data_id]); //retrieve from cache
    ...
    const dummy= {}; //or re-link original state path with cache
    state.set({
        global_cache: {
            [data_id]: dummy
        },
        views:{
            view_a: {
                data: dummy
            }
        }
    })
}

State relationship

If two states is a same object, you should anchoring them with a same well known path. So any changes automatically be synchronized.

function get_post_data(){
    state.set({
        users: {
            [user_id]: data.owner // anchoring owner object into "users/id"
        },
        posts: {
            [post_id]: data
        }
    })
}

function update_user_data(){
    state.set({
        users: {
            [user_id]: data // this change will also update previous post's owner.
        }
    });
}

Communication between components

The sample create 4 same components at different contexts and an anchor at root context. There are 2 different update function: one without state anchoring and one with state anchoring.

<SvgInput x="82" y="58" state={input1} />
<SvgInput x="357" y="58" state={input2} />
<SvgInput x="80" y="290" state={input4} />
<SvgInput x="357" y="290" state={input3} />
<SvgAnchor x="227" y="174" state={state} />

export function updateText(state, value) {
    //clear archor
    state.set({
        item: undefined
    });

    state.set({
        item: {
            value
        }
    });
}

export function updateTextWithAnchor(state, value) {
    const item = {
        value
    };
    state.set({
        "#": {
            item: item
        },
        item: item
    });
}

updateTextWithAnchor use reserved property “#” which tell gstate put the value into root context regardless current context. The method help encapsulation components link their local state with well-known-path (from root). Because all 4 components link with the same well-known-path /item, update one place will update all 4.

Components could use anchoring to root state to register service points. Any components want to communicate with the components, they should interact with those service points without care about where the components are.

function createModalDialog(state){
    const dialog = {
        visibility: false
    }
    state.set({
        "#":{
            main_dialog: dialog // service point
        },
        dialog: dialog
    });
}


function showDialog(state) {
    state.set({
        visibility: true
    })
}

// Call showDialog from anywhere
showDialog(state.path("#.main_dialog"));

Components communication via root anchoring.

results matching ""

    No results matching ""