Install Megalith through npm or a CDN.
npm install --save megalith
ES6 module:
import * as megalith from 'megalith';
CommonJS:
var megalith = require('megalith');
Script tag:
<script src="https://unpkg.com/megalith@latest"></script>
Start off by extending the Megalith Store
class and setting some initial
state:
import { Store } from 'megalith';
class App extends Store {
// Set the initial state
// Typically an object is used but numbers, strings, and arrays also work
initialState = {
counter: 0,
};
}
const app = new App();
app.counter; // => 0
app.state; // => { counter: 0 }
Note: while you can use megalith without ES6+ syntax and features (see ES5), we are using them throughout these examples. Read up on classes, class properties, modules, object spreads, and decorators.
Next, let's add an action method.
The @action
decorator is used to mark which methods change application state.
Instead of mutating the state directly however, action methods return a mutated
copy of the current state:
import { Store, action } from 'megalith';
class App extends Store {
initialState = {
counter: 0,
};
@action increment() {
// Return a mutated copy of the entire state object
return {
...this.state,
counter: this.counter + 1,
};
}
}
const app = new App();
app.increment();
app.counter; // => 1
When we call increment()
, our method is hijacked and an action is created and
dispatched to our App
store instead. The store then calls our action method,
replacing the state with the return value.
The action itself would look something like:
{
// The action type matches the action method name
type: 'increment',
// The action payload holds the arguments you passed into the action method
payload: []
}
To illustrate how actions work we can dispatch
our own actions:
const app = new App();
app.counter; // => 0
app.dispatch({ type:'increment', payload:[] });
app.counter; // => 1
We can also keep track of what actions are called by subscribing to a Store
:
const app = new App();
app.events.on({
type: 'increment',
handler: event => {
event.action.type === 'increment'; // => true
event.store === app; // => true
},
});
app.increment();
If we like, we can save the complete application state after each event as a powerful debugging tool or an easy undo/redo feature.
import { snapshot } from 'megalith';
const app = new App();
const history = [];
app.events.all(event => history.push(snapshot.create(event.store)));
app.increment();
history; // => [{ count:0 }, { count:1 }]