To install the latest stable version, run the following command:
npm install killua
- Get data from local storage
- Set data to local storage
- SSR friendly
- TypeScript friendly
- Auto update in other tabs
- Auto update in other components
- Set expiration timer
- Encrypt local storage data
- Config file for configuration management
- Reducer for state management
- Selector for data access
- Create a "thunders" directory for the thunder configuration.
- Create the thunder configuration file, for example: "counter.ts".
- Set up the configuration:
import { thunder } from "killua";
import { ThunderType } from "killua/types/thunder.type";
const thunderCounter: ThunderType = thunder({
key: "counter",
encrypt: false,
default: 1,
expire: 1,
reducers: {
increment: (thunder: number) => thunder + 1,
incrementWithPayload: (thunder: number, payload: number) => thunder + payload,
reset: () => 1,
},
selectors: {
getCounterPlusOne: (thunder: number) => thunder + 1,
getCounterPlusPayload: (thunder: number, payload: number) => thunder + payload,
},
});
export { thunderCounter };
- Thunder type definition:
type ThunderType = {
key: string; // Unique key for local storage, without starting with "thunder" (e.g., "thunderCounter")
encrypt: boolean;
expire: null | number; // null to disable the expiration timer, or a number indicating the expiration time in minutes
default: any; // Initial value for the thunder
reducers?: {
[key: string]: (thunder: any, payload: any) => any;
};
selectors?: {
[key: string]: (thunder: any, payload: any) => any;
}
};
- Use the thunder configuration in your component:
import { thunderCounter } from "../thunders/counter";
import { useKillua } from "killua";
const Counter = () => {
// all desctructer property is optional
const {
thunder: thunderCounterState,
setThunder: thunderCounterSetState,
reducers: thunderCounterReducers,
selectors: thunderCounterSelectors,
} = useKillua<number>(thunderCounter);
return (
<>
<h2> === Thunder === </h2>
<h2>Counter: {thunderCounterState}</h2>
<hr />
<h2> === Set Thunder === </h2>
<button onClick={() => thunderCounterSetState((prev: number) => prev + 1)}>Set Thunder with callback</button>
<button onClick={() => thunderCounterSetState(12)}>Set Thunder without callback</button>
<hr />
<h2> === Reducers === </h2>
<button onClick={() => thunderCounterReducers.increment()}>Increment</button>
<button onClick={() => thunderCounterReducers.incrementWithPayload(5)}>Increment with payload</button>
<button onClick={() => thunderCounterReducers.reset()}>Reset</button>
<hr />
<h2> === Selectors === </h2>
<button onClick={() => console.log(thunderCounterSelectors.getCounterPlusOne())}>Get counter with plus one</button>
<button onClick={() => console.log(thunderCounterSelectors.getCounterPlusPayload(10))}>Get counter with plus payload</button>
</>
)
};
export default Counter;
- Create a "thunders" directory for the thunder configuration.
- Create the thunder configuration file, for example: "counter.js".
- Set up the configuration:
import { thunder } from "killua";
const thunderCounter = thunder({
key: "counter",
encrypt: false,
default: 1,
expire: 1,
reducers: {
increment: (thunder) => thunder + 1,
incrementWithPayload: (thunder, payload) => thunder + payload,
reset: () => 1,
},
selectors: {
getCounterPlusOne: (thunder) => thunder + 1,
getCounterPlusPayload: (thunder, payload) => thunder + payload,
},
});
export { thunderCounter };
- Use the thunder configuration in your component:
import { thunderCounter } from "../thunders/counter";
import { useKillua } from "killua";
const Counter = () => {
// all desctructer property is optional
const {
thunder: thunderCounterState,
setThunder: thunderCounterSetState,
reducers: thunderCounterReducers,
selectors: thunderCounterSelectors,
} = useKillua(thunderCounter);
return (
<>
<h2> === Thunder === </h2>
<h2>Counter: {thunderCounterState}</h2>
<hr />
<h2> === Set Thunder === </h2>
<button onClick={() => thunderCounterSetState((prev) => prev + 1)}>Set Thunder with callback</button>
<button onClick={() => thunderCounterSetState(12)}>Set Thunder without callback</button>
<hr />
<h2> === Reducers === </h2>
<button onClick={() => thunderCounterReducers.increment()}>Increment</button>
<button onClick={() => thunderCounterReducers.incrementWithPayload(5)}>Increment with payload</button>
<button onClick={() => thunderCounterReducers.reset()}>Reset</button>
<hr />
<h2> === Selectors === </h2>
<button onClick={() => console.log(thunderCounterSelectors.getCounterPlusOne())}>Get counter with plus one</button>
<button onClick={() => console.log(thunderCounterSelectors.getCounterPlusPayload(10))}>Get counter with plus payload</button>
</>
)
};
export default Counter;
- Create app/providers.tsx and wrap the Component with the SSRKilluaProvider:
'use client';
import { SSRKilluaProvider } from 'killua';
export function Providers({ children }: { children: React.ReactNode }) {
return (
<SSRKilluaProvider>
{children}
</SSRKilluaProvider>
);
}
- Create a "thunders" directory for the thunder configuration.
- Create the thunder configuration file, for example: "counter.ts".
- Set up the configuration:
import { thunder } from "killua";
import { ThunderType } from "killua/types/thunder.type";
const thunderCounter: ThunderType = thunder({
key: "counter",
encrypt: false,
default: 1,
expire: 1,
reducers: {
increment: (thunder: number) => thunder + 1,
incrementWithPayload: (thunder: number, payload: number) => thunder + payload,
reset: () => 1,
},
selectors: {
getCounterPlusOne: (thunder: number) => thunder + 1,
getCounterPlusPayload: (thunder: number, payload: number) => thunder + payload,
},
});
export { thunderCounter };
- Thunder type definition:
type ThunderType = {
key: string; // Unique key for local storage, without starting with "thunder" (e.g., "thunderCounter")
encrypt: boolean;
expire: null | number; // null to disable the expiration timer, or a number indicating the expiration time in minutes
default: any; // Initial value for the thunder
reducers?: {
[key: string]: (thunder: any, payload: any) => any;
};
selectors?: {
[key: string]: (thunder: any, payload: any) => any;
}
};
- Use the thunder configuration in your component:
import { thunderCounter } from "../thunders/counter";
import { useKillua } from "killua";
const Counter = () => {
// all desctructer property is optional
const {
thunder: thunderCounterState,
setThunder: thunderCounterSetState,
isReadyInSsr: thunderCounterIsReadyInSsr,
reducers: thunderCounterReducers,
selectors: thunderCounterSelectors,
} = useKillua<number>(thunderCounter);
return (
<>
<h2> === Thunder === </h2>
<h2>Counter: {thunderCounterIsReadyInSsr ? thunderCounterState : 'wait ...'}</h2>
<hr />
<h2> === Set Thunder === </h2>
<button onClick={() => thunderCounterSetState((prev: number) => prev + 1)}>Set Thunder with callback</button>
<button onClick={() => thunderCounterSetState(12)}>Set Thunder without callback</button>
<hr />
<h2> === Reducers === </h2>
<button onClick={() => thunderCounterReducers.increment()}>Increment</button>
<button onClick={() => thunderCounterReducers.incrementWithPayload(5)}>Increment with payload</button>
<button onClick={() => thunderCounterReducers.reset()}>Reset</button>
<hr />
<h2> === Selectors === </h2>
<button onClick={() => console.log(thunderCounterSelectors.getCounterPlusOne())}>Get counter with plus one</button>
<button onClick={() => console.log(thunderCounterSelectors.getCounterPlusPayload(10))}>Get counter with plus payload</button>
</>
)
};
export default Counter;