Skip to content

Commit a9938e2

Browse files
authored
Merge pull request #7 from sultan99/feat/context-state
v.1.2.0
2 parents bdaa0d8 + acb75c9 commit a9938e2

File tree

16 files changed

+1858
-1133
lines changed

16 files changed

+1858
-1133
lines changed

โ€ŽCHANGELOG.mdโ€Ž

Lines changed: 39 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -1,85 +1,58 @@
1-
# Change Log
1+
## v1.2.0
2+
**Features**
23

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

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

8-
**Note:** Version bump only for package holycow
8+
**Bug fix**
99

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

12+
## v1.1.1
13+
**Bug fix**
1114

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

17+
## v1.1.0
18+
**Feature**
1319

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

22+
## v1.0.0
23+
**Features**
1624

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

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

33+
๐ŸŽฌ Actions
2134

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

38+
๐Ÿงฎ Computed values
2339

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

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

47+
- Update packages
48+
- Remove Lerna
2749

28-
### Bug Fixes
50+
## v0.1.0
51+
**Features**
2952

30-
* **state:** typings ([022d4d8](https://github.com/sultan99/holycow/commit/022d4d813ab4c6676500872ac250f6eb3b97ebdf))
31-
32-
33-
34-
35-
36-
# [0.1.0-alpha.4](https://github.com/sultan99/holycow/compare/v0.1.0-alpha.3...v0.1.0-alpha.4) (2021-10-07)
37-
38-
39-
### Bug Fixes
40-
41-
* **state:** remove setters on unmount ([e0b8f46](https://github.com/sultan99/holycow/commit/e0b8f46eec36be51452c543cb3a17efb84c3f4e4))
42-
43-
44-
45-
46-
47-
# [0.1.0-alpha.3](https://github.com/sultan99/holycow/compare/v0.1.0-alpha.2...v0.1.0-alpha.3) (2021-10-07)
48-
49-
50-
### Bug Fixes
51-
52-
* **state:** set currying function & typings ([f97b566](https://github.com/sultan99/holycow/commit/f97b566ac1af8f2f757edcc16a6ed21974c32b75))
53-
54-
55-
56-
57-
58-
# [0.1.0-alpha.2](https://github.com/sultan99/holycow/compare/v0.1.0-alpha.1...v0.1.0-alpha.2) (2021-09-21)
59-
60-
61-
### Bug Fixes
62-
63-
* **state:** typing & package updates ([bc4f139](https://github.com/sultan99/holycow/commit/bc4f13915dd775de4a61ab07b823462816325f73))
64-
65-
66-
67-
68-
69-
# [0.1.0-alpha.1](https://github.com/sultan99/holycow/compare/v0.1.0-alpha.0...v0.1.0-alpha.1) (2021-06-13)
70-
71-
72-
### Bug Fixes
73-
74-
* types and import ([9719f85](https://github.com/sultan99/holycow/commit/9719f8557cbcb7b9b5c956f83c2f9c69fab42618))
75-
76-
77-
78-
79-
80-
# 0.1.0-alpha.0 (2021-06-09)
81-
82-
83-
### Features
84-
85-
* **state:** add create state function ([17cf2de](https://github.com/sultan99/holycow/commit/17cf2def4003a398f1d1a38c060aaead3be59e27))
53+
- ๐Ÿง  Greedy rendering
54+
- ๐Ÿงฎ Computed values with hook nesting
55+
- ๐ŸŽฌ Actions
56+
- ๐Ÿ—ฟ Static variables
57+
- ๐Ÿคน Selectors
58+
- ๐Ÿ“Ž Strongly typed with TypeScript.

โ€ŽREADME.mdโ€Ž

Lines changed: 65 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ An action is any piece of code that modifies the state and targets some specific
103103

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

106-
```js
106+
```jsx
107107
import {createState, action} from '@holycow/state'
108108

109109
const useAuth = createState({
@@ -164,7 +164,7 @@ useUser.set('address.street', 'Spooner')
164164
### ๐Ÿงฎ Computed values
165165
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.
166166

167-
```js
167+
```jsx
168168
import {createState, computed} from '@holycow/state'
169169

170170
const useUser = createState({
@@ -255,6 +255,67 @@ const {set: setUser} = useUser()
255255
const {set: setMessage} = useMessages()
256256
```
257257

258+
### ๐Ÿ—ƒ๏ธ Context state
259+
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.
260+
261+
- Greedy rendering, meaning that only updated values trigger component rendering.
262+
- Computed values with caching and hook nesting.
263+
- Asynchronous actions.
264+
265+
However, the state hook can only be used inside React components and does not support subscription to the state changes.
266+
267+
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.
268+
269+
```jsx
270+
import {action, createContextState} from '@holycow/state'
271+
272+
const [Context, useCounter] = createContextState({
273+
// ๐Ÿ‘‡ the context initial state
274+
count: 0,
275+
name: `Untitled`,
276+
increment: action(({set}) => () =>
277+
set(`count`, value => value + 1)
278+
),
279+
})
280+
281+
const Label = () => {
282+
// same as the holy state hook ๐Ÿ‘‡
283+
const {name, count} = useCounter()
284+
return <h1>{name}: {count}</h1>
285+
}
286+
287+
const Button = () => {
288+
const {increment} = useCounter()
289+
return (
290+
<button onClick={increment}>
291+
Increment
292+
</button>
293+
)
294+
}
295+
296+
// only assigned props {name, count, increment}
297+
// will override the initial context state
298+
// undefined props ๐Ÿ‘‡ will be ignored
299+
const Counter = props => (
300+
<Context value={props}>
301+
<Label/>
302+
<Button/>
303+
</Context>
304+
)
305+
306+
const App = () => {
307+
const [age, setAge] = useState(21)
308+
return (
309+
<main>
310+
// each Counter component will have it is own state
311+
<Counter name='๐Ÿ‘ counter'/>
312+
<Counter count={age} increment={() => setAge(age + 1)}/>
313+
// ๐Ÿ‘† controlled component by parent component
314+
</main>
315+
)
316+
}
317+
```
318+
258319
### ๐Ÿ“ฌ State subscriptions
259320
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.
260321

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

269330
// subscription to specific ๐Ÿ‘‡ value
270-
useUser.subscribe('address.street', () => {
271-
console.log('User street was changed!')
331+
useUser.subscribe('address.street', street => {
332+
console.log(`User street was changed to ${street}`)
272333
})
273334
```
274335

0 commit comments

Comments
ย (0)