ππ» A minimalist, functional state management library.
- Functional: Nation enforces functional programming.
- Minimal: Nation is a fully functional state management lib weighing less than 500 byte.
- Easy: Nation's API is as minimal as possible.
- Immutable: State can only be set in actions or using
setState. - Reactive: The update event is emitted on every state change.
State management libraries often weigh multiple kilobytes, even though most of the time you just need a small part of their API. Nation's approach is different - nation only includes the bare minimum state management functionality.
Nation enforces functional programming, this allows nation to be even tinier and makes you code more explicit.
$ npm install nation
const nation = require('nation');
const ship = nation({
initial: () => ({
swimming: true
})
});
console.log(ship.state().swimming);
// => trueship.action(state => ({
setSwimming: (val) => {
state().swimming = val;
},
setName: (val) => {
state().name = val;
}
}));
ship.actions().setName('merry');
ship.actions().setSwimming(false);
console.log(ship.state().name);
// => 'merry'
console.log(ship.state().swimming);
// => falseship.setState({
name: 'enterprise',
swimming: true
})
console.log(ship.state().name);
// => 'enterprise'
console.log(ship.state().swimming);
// => trueComputed properties can be accessed like normal state values. They are computed every time the state changes.
ship.computed(state => ({
swimmingName: () => {
return `The ${state().swimming} is ${state().name == true ? 'swimming' : 'not swimming'}.`;
}
}));
console.log(ship.state().swimmingName);
// => 'The enterprise is swimming.'Nations lifecycle consists of a single method: onChange.
ship.onChange((state) => {
console.log('The state has changed - State: ', state);
});Nation treats every function the same no matter if it's sync or async. The only difference is, that in async functions you have to use setState to set state.
ship.action(state => ({
setAsync: async () => {
ship.setState({ asyncValue: await asyncFn() })
}
}));
ship.actions().setAsync();
// Wait
console.log(ship.state().asyncValue);Nation state can be nested, the onChange event will be passed on, so even nested state is reactive.
Nested state cannot be set using actions, you have to use setState.
const cargo = nation({
initial: () => {
loaded: true
}
});
ship.setState({
cargo
});
ship.onChange((state) => {
console.log('Loaded state: '+ state.loaded);
})
cargo.setState({
loaded: false
});
// => Loaded state: falseMIT Β© Tobias Herber