Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
  • Loading branch information
daz4126 committed Jan 4, 2024
2 parents f2ca4c5 + 81d9ce9 commit ee38dfc
Showing 1 changed file with 34 additions and 37 deletions.
71 changes: 34 additions & 37 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,49 +10,46 @@ _small, simple & speedy state management_

</div>

**NANNY STATE** is a super *small* library that makes it super *simple* to build super *speedy* web apps.
**NANNY STATE** is a *small* reactive state library that makes it *simple* to build *speedy* web apps.

- **SUPER SMALL** - only 3kb minified and zipped
- **SUPER SIMPLE** - a single state object and update method
- **SUPER SPEEDY** - automatic page renders that are blazingly fast
It does everything React does, but without the build process, JSX or a virutal DOM ... and it's a fraction of the size …

## THE STATE IS EVERYTHING
- **SMALL** - less than 4kb minified and zipped
- **SIMPLE** - a single state object with some useful helper methods
- **SPEEDY** - automatic page renders that are blazingly fast

**NANNY STATE** stores everything in a single state object and automatically re-renders the view whenever the state changes. This helps to keep your code more organized and easier to maintain without the bloat of other libraries.

* A single import and no build process
* State is shared across the whole app
* Everything is written in vanilla JS and HTML
* Built-in router makes it easy to build single page web apps
* Local storage can be added with a single line of code

**NANNY STATE** is easy learn - just follow the [examples](#examples) below and you'll see some impressive results in just a few lines of code.

## QUICK START

All you need in a **NANNY STATE** app is a view component and `State` object:
It uses a purely declarative notation and everything is written in Vanilla JS and HTML. To get started, just set the initial state and write the view - check out the example below:

```javascript
import Nanny from "nanny-state"
// View Code
const Counter = state => state.HTML`
<h1>${state.count}</h1>
// View is a tag function that accepts the state as a parameter
const View = state => state.HTML`
<h1>❤️ ${state.count}</h1>
<div>
<button onclick=${e => state.Decrement("count")}>-</button>
<button onclick=${e => state.Increment("count")}>+</button>
<button onclick=${event => state.Decrement("count")}>👎</button>
<button onclick=${event => state.Increment("count")}>👍</button>
</div>`
// Initial State
const State = {
count: 0,
View: Counter
View
}
// Start the Nanny State!
Nanny(State)
```

The view component in this example is the `Counter` function. It accepts the state as its only parameter and returns a string of HTML based on the current state. The `State` object contains all the initial data values.
## THE STATE IS EVERYTHING

**NANNY STATE** stores everything in a single state object and automatically re-renders the view whenever the state changes. This helps to keep your code more organized and easier to maintain without the bloat of other libraries.

* Centralized state object that is shared across the whole app
* Built-in router makes it easy to build single page web apps
* Local storage can be added with a single line of code
* Calculations and Effects
* Sequential updates in a single line of code
* Everything is written in vanilla JS and HTML
* A single import and no build process

This example can be seen [on Codepen](https://codepen.io/daz4126/pen/mdveMBy)

## WHAT IS NANNY STATE?

Expand All @@ -64,13 +61,13 @@ This example can be seen [on Codepen](https://codepen.io/daz4126/pen/mdveMBy)

</div>

In NANNY STATE, the state is everything. It is the single source of truth in the application where all the app data is stored. The view is an HTML representation of the state. When a user interacts with the page, they trigger event handlers defined in the view that hook into the state's `Update` method. This is the only way the state can be changed and ensures that any updates are deterministic with predictable outcomes. Whenever the state is updated, the view is automatically re-rendered to reflect the changes that were made.
In NANNY STATE, the state is everything. It is a single object that is the ultimate source of truth in the application where all the app data is stored. This means that any changes to the application remain consistent and easier to keep track of. The view is an HTML representation of the state and the Nanny State's helper methods ensure that any updates are deterministic with predictable outcomes. When the state is updated, the view is automatically re-rendered to reflect the changes that were made.

## BACKGROUND

NANNY STATE was inspired by [Hyperapp](https://hyperapp.dev) and [Redux](https://redux.js.org) and uses the [µhtml](https://github.com/WebReflection/uhtml) library for rendering. It is open source software; please feel free to help out or contribute.
NANNY STATE was inspired by [Hyperapp](https://hyperapp.dev) and [Redux](https://redux.js.org) and uses the amazing [µhtml](https://github.com/WebReflection/uhtml) library for rendering. It is open source software; please feel free to help out or contribute.

The name is a [British phrase](https://en.wikipedia.org/wiki/Nanny_state) for an overly protective, centralised government. In a similar way, NANNY STATE stores all the app data centrally and controls how it is updated.
The name is a [British phrase](https://en.wikipedia.org/wiki/Nanny_state) for an overly protective, centralised government. In a similar way, NANNY STATE stores all the app data centrally and controls how it is used.

## INSTALLATION

Expand All @@ -94,7 +91,7 @@ If you use ES Modules, you don't need NPM. You can import from a CDN URL in your

```html
<script type="module">
import Nanny from 'https://cdn.skypack.dev/nanny-state'
import Nanny from "https://esm.sh/nanny-state"
</script>
```

Expand Down Expand Up @@ -122,9 +119,9 @@ const State = {
}
```

The `View` in **NANNY STATE** is a method of the state (*everything* is part of the state!). It is a function that always accept the state as its only parameter. This means it has access to all the properties of the state, including the `state.HTML` function that is just an alias for µhtml's `html` function. This is a tag function that returns the HTML code that we want to display on the page, which in this case is a level 1 heading that says "Hello World".
The `View` in **NANNY STATE** is a method of the state (*everything* is part of the state!). It is a function that accepts the state as its only parameter. This means it has access to all the properties of the state, including the `state.HTML` function that is just an alias for µhtml's `html` function. This is a tag function that returns the HTML code that we want to display on the page, which in this case is simply a level 1 heading that says "Hello World".

Last of all, we need to call the `Nanny` function providing `State` as an argument:
Last of all, we need to call the `Nanny` function with `State` as the argument:

```javascript
Nanny(State)
Expand All @@ -142,7 +139,7 @@ You can see this code on [CodePen](https://codepen.io/daz4126/pen/gOoBryB).

All we've done so far is create a static piece of HTML. The view in **NANNY STATE** can display properties of the state using `${prop}` placeholders.

Even though `View` is a property of the State object, it's not really practical to define it directly inside `State` like we did in the last example, especially when the view code becomes quite long. Instead, we can define it as a variable named `View`, then use object-shortand notation to add this to the `State` object, like so:
Even though `View` is a property of the State object, it's not really practical to define it directly inside `State` like we did in the last example, especially when the view code becomes quite long. Instead, we can define it as a variable named `View`, then use object-shortand notation to add this to the `State` object, like this:

```javascript
const View = state => state.HTML`<h1>Hello ${state.name}</h1>`
Expand All @@ -157,7 +154,7 @@ Even though, outwardly, this example looks identical to the previous one, it's d

You can see this code on [CodePen](https://codepen.io/daz4126/pen/jOYeqoN).

Our next job is to make the view dynamic. Let's start by adding a button:
Now, let's make the view dynamic by adding a button:

```javascript
const View = state =>
Expand All @@ -167,11 +164,11 @@ const View = state =>

The button element has an inline `onclick` event listener. When the button is clicked the inline event handler is called. The purpose of this function is to update the state object so the 'name' property changes to 'Nanny State'. This is exactly what the built-in `state.Update` function is for.

The `state.Update` function to the *only* way to update the state. In this example it will change the value of the 'name' property when the button is clicked. This is really easy to do - simply pass an object representing the new state as an argument to the function.
`Update` is a built-in method of the state object and is the *only* way to update the state (although there are also some useful helper methods that use the `Update` method behind the scenes ... see later!). It works by mapping the old state to the new state. In this example we are changing the value of the 'name' property from its inital value of "World" to "Nanny State". This is really easy to do - simply pass an object representing the new state as an argument to the function.

In the example above, we pass the object `{name: "Nanny State"}` as an argument to the `state.Update` function. Note that you ony have to include any properties of the State that need updating in this object(**NANNY STATE** assumes that all the other properties will stay the same). The view will then automatically be re-rendered using µhtml, which only updates the parts of the view that have actually changed. This means that re-rendering after a state update is fast and efficient.
In the example above, we pass the object `{name: "Nanny State"}` as an argument to the `Update` function. Note that you ony have to include any properties of the State that need updating in this object (NANNY STATE assumes that all the other properties will stay the same). The view will then automatically be re-rendered using µhtml, which only updates the parts of the view that have actually changed. This means that re-rendering after a state update is fast and efficient.

We now have everything wired up correctly. When the user clicks the button, the event handler uses the `state.Update` function to update the 'name' property to 'Nanny State' and re-renders the page based on this new state.
We now have everything wired up correctly. When the user clicks the button, the event handler uses the `Update` function to update the 'name' property to 'Nanny State' and re-renders the page based on this new state.

You can see this code on [CodePen](https://codepen.io/daz4126/pen/gOoBrJB). Try clicking the button to see the view change!

Expand Down

0 comments on commit ee38dfc

Please sign in to comment.