usage
Create slice configuration file
slice
refers to a key within localStorage.Whatever the useKillua
hook returns, the slice
function also returns.
Use the useKillua hook within the React framework, and as long as you
don't have access to it, use the slice function.
- Create a
slices
directory for the thunder configuration. - Create the slice configuration file, for example:
counter.ts
. - Set up the slice configuration:
import { slice } from 'killua';
export const counterSlice = slice({
key: 'counter', // unique key for localStorage
defaultClient: 1 as number // default value for client-side application
});
Get data
- Within a React component, utilize the
useKillua
hook :
import { useKillua } from 'killua';
import { counterSlice } from '@/slices/counter';
export default function Component() {
const localstorageCounter = useKillua(counterSlice);
return (
<div>
<p>{counterSlice.get()}</p>
</div>
);
}
- Outside of a React component, employ the
slice
function :
import { counterSlice } from '@/slices/counter';
export function getCounter() {
return counterSlice.get();
}
Set data
- Within a React component, utilize the
useKillua
hook :
import { useKillua } from 'killua';
import { counterSlice } from '@/slices/counter';
export default function Component() {
const localstorageCounter = useKillua(counterSlice);
return (
<div>
{/* without callback */}
<button onClick={() => counterSlice.set(0)}>Set counter to zero</button>
{/* with callback */}
<button onClick={() => counterSlice.set(prev => prev + 1)}>
Increment counter
</button>
</div>
);
}
- Outside of a React component, employ the
slice
function :
import { counterSlice } from '@/slices/counter';
// without callback
export function setCounterToZero() {
counterSlice.set(0);
}
// with callback
export function incrementCounter() {
counterSlice.set(prev => prev + 1);
}
Use selectors
- To use a selector, simply add it to the slice config :
import { slice } from 'killua';
export const counterSlice = slice({
key: 'counter',
defaultClient: 1 as number,
selectors: {
getPlusOne: value => value + 1,
getPlusWithPayload: (value, payload: number) => value + payload
}
});
- Within a React component, utilize the
useKillua
hook :
import { useKillua } from 'killua';
export default function Component() {
const localstorageCounter = useKillua(counterSlice);
return (
<div>
<p>{localstorageCounter.getPlusOne()}</p> {/* without payload */}
<p>{localstorageCounter.getPlusWithPayload(5)}</p> {/* with payload */}
</div>
);
}
- Outside of a React component, employ the
slice
function :
import { counterSlice } from '@/slices/counter';
// without payload
export function getCounterWithPlusOne() {
return counterSlice.getPlusOne();
}
// with payload
export function getCounterWithPlusWithPayload() {
return counterSlice.getPlusWithPayload(5);
}
Use reducers
- To use a reducer, simply add it to the slice config :
import { slice } from 'killua';
export const counterSlice = slice({
key: 'counter',
defaultClient: 1 as number,
reducers: {
increment: value => value + 1,
incrementWithPayload: (value, payload: number) => value + payload
}
});
- Within a React component, utilize the
useKillua
hook :
import { useKillua } from 'killua';
export default function Component() {
const localstorageCounter = useKillua(counterSlice);
return (
<div>
<button onClick={() => localstorageCounter.increment()}>
Increment counter
</button>
{/* without payload */}
<button onClick={() => localstorageCounter.incrementWithPayload(5)}>
Increment counter with payload
</button>{' '}
{/* with payload */}
</div>
);
}
- Outside of a React component, employ the
slice
function :
import { counterSlice } from '@/slices/counter';
// without payload
export function incrementCounter() {
counterSlice.increment();
}
// with payload
export function incrementCounterWithPayload() {
counterSlice.incrementWithPayload(5);
}
Using in SSR application
As long as the initial server-side rendering occurs and there is no access to
localStorage, defaultServer
will be returned. Later, when the client-side
rendering takes place, data will be fetched from localStorage and returned.
As long as defaultServer
exists in the config, both the useKillua
hook and
the slice
function will return a property named isReady
.
If this value is false
, it means that it is server-side and localStorage is
not accessible, and the returned value is defaultServer
.
If this value is true, it means that it is client-side and localStorage is accessible, and the fetched value is from localStorage.
- add
defaultServer
to the slice configuration :
import { slice } from 'killua';
export const counterSlice = slice({
key: 'counter',
defaultClient: 1 as number,
defaultServer: 2 // default value for server-side application
});
- Within a React component, utilize the
useKillua
hook :
'use client';
import { useKillua } from 'killua';
export default function Component() {
const localstorageCounter = useKillua(counterSlice);
return (
<div>
{localstorageCounter.isReady ? (
<p>{localstorageCounter.get()}</p>
) : (
<p>Loading...</p>
)}
</div>
);
}
- Outside of a React component, employ the
slice
function :
import { counterSlice } from '@/slices/counter';
export function getCounter() {
// if is server-side ? return defaultServer : return localStorage value
return counterSlice.get();
}
Obfuscate data
As long as obsfacte is present in the slice config, your data is not protected but merely obfuscated.
- To obfuscate localStorage data, simply add it to the slice config:
import { slice } from 'killua';
export const counterSlice = slice({
key: 'counter',
defaultClient: 1 as number,
obsfacte: true // obfuscate data in localStorage
});
Expire timer
If the localStorage data expires at the moment when a user is on the website
and the useKillua
hook is in use, the data will be immediately removed from
localStorage. Subsequently, the useKillua
hook will update and return the
defaultClient
value.
If the user enters the site and the data has already expired, the
defaultClient
value will be returned.
- To set an expiration time for localStorage data, simply add it to the slice config :
import { slice } from 'killua';
export const counterSlice = slice({
key: 'counter',
defaultClient: 1 as number,
expire: '1d-9h-24m-10s' // expire time for localStorage data (1 day, 9 hours, 24 minutes, 10 seconds)
});
Schema validation
If schema
exists in the configuration, when the localStorage is updated
using set
or reducers
, the data will be validated against that schema
.
If it is not valid, it will not be set on the localStorage.
If schema
is exists in the configuration, when the localStorage data is
retrieved using selectors
or get
, and if it is validated against the
schema
and found to be invalid, the defaultClient
value will be returned
instead.
- To set a schema for localStorage data, simply add it to the slice config :
import { slice } from 'killua';
export const counterSlice = slice({
key: 'counter',
defaultClient: 1 as number,
schema: z.number().min(0).max(10) // zod schema or yup schema
});