Skip to content

Commit

Permalink
Merge pull request #7 from sultan99/feat/context-state
Browse files Browse the repository at this point in the history
v.1.2.0
  • Loading branch information
sultan99 authored Feb 26, 2023
2 parents bdaa0d8 + acb75c9 commit a9938e2
Show file tree
Hide file tree
Showing 16 changed files with 1,858 additions and 1,133 deletions.
105 changes: 39 additions & 66 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,85 +1,58 @@
# Change Log
## v1.2.0
**Features**

All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
๐Ÿ—ƒ๏ธ Context state

# [0.1.0](https://github.com/sultan99/holycow/compare/v0.1.0-alpha.6...v0.1.0) (2022-04-15)
## v1.1.2

**Note:** Version bump only for package holycow
**Bug fix**

๐Ÿž [Cannot create proxy with a non-object as target or handler](https://github.com/sultan99/holycow/issues/5).

## v1.1.1
**Bug fix**

๐Ÿž [Reset removes built-in functions](https://github.com/sultan99/holycow/issues/4)

## v1.1.0
**Feature**

# [0.1.0-alpha.6](https://github.com/sultan99/holycow/compare/v0.1.0-alpha.5...v0.1.0-alpha.6) (2021-10-19)
๐Ÿ“ข Signal Events

## v1.0.0
**Features**

### Bug Fixes
- ๐Ÿƒ Atomic state updates
- ๐Ÿงฎ Computed values come with caching and lazy evaluation
- ๐Ÿ“ฌ Subscription to state changes
- ๐Ÿงฉ Utility functions (compose, curry, pick, append, update)
- ๐ŸŽฃ No external dependency, [Ramda](https://github.com/ramda/ramda) library is removed

* **state:** late updates ([0250064](https://github.com/sultan99/holycow/commit/025006499c2c885c429c0142b6a2da0c2d9ca4fd))
**Breaking changes**

๐ŸŽฌ Actions

- Actions must now be wrapped with the `action` function
- New declaration interface: `action(state => payload => { ... })`

๐Ÿงฎ Computed values

- Computed values must now be wrapped with the `computed` function
- Payload from computed functions has been removed
- New declaration interface: `computed(state => ...)`

# [0.1.0-alpha.5](https://github.com/sultan99/holycow/compare/v0.1.0-alpha.4...v0.1.0-alpha.5) (2021-10-14)
## v0.1.1
**Chore**

- Update packages
- Remove Lerna

### Bug Fixes
## v0.1.0
**Features**

* **state:** typings ([022d4d8](https://github.com/sultan99/holycow/commit/022d4d813ab4c6676500872ac250f6eb3b97ebdf))





# [0.1.0-alpha.4](https://github.com/sultan99/holycow/compare/v0.1.0-alpha.3...v0.1.0-alpha.4) (2021-10-07)


### Bug Fixes

* **state:** remove setters on unmount ([e0b8f46](https://github.com/sultan99/holycow/commit/e0b8f46eec36be51452c543cb3a17efb84c3f4e4))





# [0.1.0-alpha.3](https://github.com/sultan99/holycow/compare/v0.1.0-alpha.2...v0.1.0-alpha.3) (2021-10-07)


### Bug Fixes

* **state:** set currying function & typings ([f97b566](https://github.com/sultan99/holycow/commit/f97b566ac1af8f2f757edcc16a6ed21974c32b75))





# [0.1.0-alpha.2](https://github.com/sultan99/holycow/compare/v0.1.0-alpha.1...v0.1.0-alpha.2) (2021-09-21)


### Bug Fixes

* **state:** typing & package updates ([bc4f139](https://github.com/sultan99/holycow/commit/bc4f13915dd775de4a61ab07b823462816325f73))





# [0.1.0-alpha.1](https://github.com/sultan99/holycow/compare/v0.1.0-alpha.0...v0.1.0-alpha.1) (2021-06-13)


### Bug Fixes

* types and import ([9719f85](https://github.com/sultan99/holycow/commit/9719f8557cbcb7b9b5c956f83c2f9c69fab42618))





# 0.1.0-alpha.0 (2021-06-09)


### Features

* **state:** add create state function ([17cf2de](https://github.com/sultan99/holycow/commit/17cf2def4003a398f1d1a38c060aaead3be59e27))
- ๐Ÿง  Greedy rendering
- ๐Ÿงฎ Computed values with hook nesting
- ๐ŸŽฌ Actions
- ๐Ÿ—ฟ Static variables
- ๐Ÿคน Selectors
- ๐Ÿ“Ž Strongly typed with TypeScript.
69 changes: 65 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ An action is any piece of code that modifies the state and targets some specific

Action expects a curried function as a parameter. The first function provides the state โ€” the second one handles the action payload.

```js
```jsx
import {createState, action} from '@holycow/state'

const useAuth = createState({
Expand Down Expand Up @@ -164,7 +164,7 @@ useUser.set('address.street', 'Spooner')
### ๐Ÿงฎ Computed values
A computed value is a value returned by a specified function. The function's input can be a state value or any other hook. To avoid unnecessary computations, the computed value is cached and recomputed only when the current dependency has changed. Conceptually, computed values are similar to spreadsheets' formulas or Redux memoized selectors.

```js
```jsx
import {createState, computed} from '@holycow/state'

const useUser = createState({
Expand Down Expand Up @@ -255,6 +255,67 @@ const {set: setUser} = useUser()
const {set: setMessage} = useMessages()
```

### ๐Ÿ—ƒ๏ธ Context state
Context state is a multiple-instance state with its own scope. It is designed to create reusable nested components that share one state with their child components. It is similar to the React Context, but powered by holy state features.

- Greedy rendering, meaning that only updated values trigger component rendering.
- Computed values with caching and hook nesting.
- Asynchronous actions.

However, the state hook can only be used inside React components and does not support subscription to the state changes.

The `createContextState` function creates a state and returns a tuple with a context provider and a hook. The initial context state can be overridden by a parent component. This allows you to create uncontrolled, controlled, or partially controlled components.

```jsx
import {action, createContextState} from '@holycow/state'

const [Context, useCounter] = createContextState({
// ๐Ÿ‘‡ the context initial state
count: 0,
name: `Untitled`,
increment: action(({set}) => () =>
set(`count`, value => value + 1)
),
})

const Label = () => {
// same as the holy state hook ๐Ÿ‘‡
const {name, count} = useCounter()
return <h1>{name}: {count}</h1>
}

const Button = () => {
const {increment} = useCounter()
return (
<button onClick={increment}>
Increment
</button>
)
}

// only assigned props {name, count, increment}
// will override the initial context state
// undefined props ๐Ÿ‘‡ will be ignored
const Counter = props => (
<Context value={props}>
<Label/>
<Button/>
</Context>
)

const App = () => {
const [age, setAge] = useState(21)
return (
<main>
// each Counter component will have it is own state
<Counter name='๐Ÿ‘ counter'/>
<Counter count={age} increment={() => setAge(age + 1)}/>
// ๐Ÿ‘† controlled component by parent component
</main>
)
}
```

### ๐Ÿ“ฌ State subscriptions
We can subscribe to the state changes and get notified when the state is updated. The `subscribe` function accepts a callback function as a parameter and returns another function for unsubscription.

Expand All @@ -267,8 +328,8 @@ const unsubscribe = useUser.subscribe(state => {
unsubscribe() // canceling subscription ๐Ÿ‘†

// subscription to specific ๐Ÿ‘‡ value
useUser.subscribe('address.street', () => {
console.log('User street was changed!')
useUser.subscribe('address.street', street => {
console.log(`User street was changed to ${street}`)
})
```

Expand Down
Loading

0 comments on commit a9938e2

Please sign in to comment.