outer-state
v0.0.3
Published
outer-state is a simple but extremely powerful state management facility for ReactJS applications. It promotes and facilitates keeping 100% of the business logic out of React. Instead it allows all logic to be in vanilla TypeScript/JavaScript files. This
Downloads
2
Maintainers
Readme
outer-state
Write simpler cleaner code faster.
outer-state is a simple yet powerful state management library for ReactJS applications.
It is 100% boilerplate free. There is zero setup or configuration. The learning curve is tiny. It just works.
It promotes and facilitates moving all business logic out of React and into vanilla Typescript/Javascript files.
This massively reduces application complexity.
It also massively reduces unit test complexity while promoting increased test quality and coverage.
outer-state is enjoyable to use.
Installation
yarn add outer-state
or
npm install outer-state
Basic Usage
interface TaskTrackerState {
secondsElapsed: number;
itemsComplete: string[];
}
Create a store (multiple stores are strongly encouraged)
import { createStore } from 'outer-state';
const taskTrackerState = createStore<TaskTrackerState>({
secondsElapsed: 0,
itemsComplete: []
});
Update State
Updating state can be done inside vanilla TypeScript files. This is encouraged.
Note that updateStore
accepts partial objects, i.e. you do not have to specify a value for each store property, only those you wish to update.
Functional Variant
taskTrackerState.updateStore((store) => ({secondsElapsed: store.secondsElapsed + 1}));
Object Variant
taskTrackerState.updateStore({secondsElapsed: 23});
Read State (outside of a Component or custom-hook)
const {secondsElapsed, itemsComplete} = taskTrackerState.data();
Read State (inside a Component or custom-hook)
Using useStore()
will cause a rerender when any of the values change
const {secondsElapsed, itemsComplete} = taskTrackerState.useStore();
return (
<div>
<div>Seconds Elapsed: {secondsElapsed}</div>
<div>
<h2>itemsComplete</h2>
<ul>
{itemsComplete.map((item) => <li key={item}>{item}</li>)}
</ul>
</div>
</div>
)
useStore(initialProps)
useStore
can accept initial props.
const {secondsElapsed, itemsComplete} = taskTrackerState.useStore({secondsElapsed: 23})
This is particularly convenient in for example a NextJS application where props are received during server rendering.
Similar to useState(defaultValue)
initial props will only be set once. Subsequent rerenders will not update the store again.
Note that the store is a singleton so this applies even when useStore
is called in multiple components. Once useStore
is called once, initial values are ignored after that.
// A NextJS route
export default async function Page() {
const data = await getData();
return <MyComp {...data} />
}
export function MyComp(data: TaskTrackerState) {
const {secondsElapsed, itemsComplete} = taskTrackerState.useStore(data);
return (
<div>
<div>Seconds Elapsed: {secondsElapsed}</div>
<div>
<h2>itemsComplete</h2>
<ul>
{itemsComplete.map((item) => <li key={item}>{item}</li>)}
</ul>
</div>
</div>
)
}
Examples and Demos
To run the example in this repo simply navigate to /example
and run yarn install
followed by yarn start
. The example will then be available at http://localhost:1234
.