nalanda Documentation
Nalanda is still in early release. We are working hard to make it production ready.
Installation
Use your preferred package manager to install:
# react codebase
npm install @nalanda/core @nalanda/react
# other codebases
npm install @nalanda/core
@nalanda/core
is the core library that can be used with any framework.
Read more about using Nalanda with
Creating a Slice
Start by crafting a simple counter slice:
import { createKey } from '@nalanda/react';
// The key is a local helper used to define various components of your slice.
const key = createKey('counterSlice', []);
// State fields define part of your state.
const counter = key.field(0);
// Actions define how a field/s should be updated.
function increment() {
return counter.update((c) => c + 1);
}
// A slice serves as an interface, revealing the specified fields
// and actions to the entire application.
export const counterSlice = key.slice({
counter,
increment
});
Setting up the Store
At the root of your React app, set up a store and encapsulate your app with the StoreProvider component:
import { StoreProvider } from '@nalanda/react';
import { createStore } from '@nalanda/core';
import { counterSlice } from './counter-slice';
// Establish a global store incorporating your slices.
const store = createStore({
slices: [counterSlice],
});
ReactDOM.render(
<StoreProvider store={store}>
<App />
</StoreProvider>,
document.getElementById('root')
);
Displaying the counter
With the store in place, employ the useSlice hook to access the state and actions from the slice:
import { useTrack, useStore } from '@nalanda/react';
import { counterSlice } from './counterSlice';
export function Counter() {
// useTrack will re-render the component any time the `counter` value changes.
const { counter } = useTrack(counterSlice);
const store = useStore();
const increment = () => {
// Dispatch an action to update the slice
store.dispatch(counterSlice.increment());
};
return (
<div>
<h1>Counter</h1>
<p>{counter}</p>
<button onClick={increment}>increment</button>
</div>
);
}
Isn't That Quite a Bit for Just a Counter?
Before addressing that, consider the following code, inspired by a real-world application:
// Somewhere within a vast 5,000 lines of code
() => {
counter += 1; // A simple counter increment
}
It seems straightforward, doesn’t it? Yet, ponder on these questions:
- What's the scope of the
counter
variable? - Should other parts of the app have the capability to modify it?
- How can I prevent unintended modifications from other sections of the app?
- What if I decide to alter the counter's implementation? What other parts of the app will be affected?
While this might seem boilerplat-ish for a simple counter, it's essential to recognize that most applications are more complex than basic counters. They will contain many slices and numerous components, interacting with those slices in unforeseen ways. As your application evolves, you can add more slices to the store and integrate additional components to make use of them. Such a design ensures that, no matter how much your application grows, state management remains streamlined and more importantly intuitive.
The Complete Counter Example
Below is the full code for the counter demonstration. Feel free to interact and experiment with this example: