Encapsulation

To implement encapsulation with gstate using:

  1. Isolated sub state by state.path API.
  2. Pure function commands with state as parameter.

Same components but different states.

Define component with state as a property and it's behaviors as pure functions with state as a parameter.

// Pure function command with state as a parameter.
function incrementCounter(state){
      const counter = state.get("counter") || 0;
      state.set({ counter: counter+1})
} 

// Component with state as a property
const Counter = ({state}) => ( 
     <button onClick={() => incrementCounter(state)}>+</button>
)

Now, we could use the component in anywhere with different state path.

<Counter state={state.path("top")}/>   

<Counter state={state.path("bottom")}/>

Each components should display and mutate it's own state path.

Dynamic components.

It is easy to create dynamic state path.

const AddDynamicCounters = ({ state, numberOfCounters}) => {
      const counterArray = [];    
      for (let i = 0; i < numberOfCounters; i++) {
            counterArray.push(i);    
      }
      return (
         <div>{counterArray.map(id => <Counter state={state.path(i)}/>)}</div>
     )
}

Encapsulate components (views) with commands (behaviors)

It is recommended that you should separate views with behaviors, so those behaviors could be reused with different UI frameworks.

But in some cases, encapsulate both view and behaviors is valid. For example divide a complex application into modules. It could be implemented by combine a create command and behaviors into a simple module.

// This is counter.js module which encapsulate counter component with incrementCounter command.

const Counter = gstate({ counter: 1 },(props, data) => ( 
    <button onClick={() => incrementCounter(props.state)}>+</button>
))   

function createCounter(state){
   return <Counter state={state} />
}

function incrementCounter(state){
      const counter = state.get("counter") || 0;
      state.set({ counter: counter+1})
}

Use the counter.js module to create Counter component.

{createCounter(state.path("top"))}
{createCounter(state.path("bottom"))}

results matching ""

    No results matching ""