Skip to content

Commit 97c6351

Browse files
authored
docs: updated readme with more API info (#6)
* docs: updated readme with more API info * removed .DS_store files * removed .DS_Store files * docs: removed watch and replaced it with effect * format * docs: removed watch from readme
1 parent 4ded45d commit 97c6351

1 file changed

Lines changed: 158 additions & 14 deletions

File tree

README.md

Lines changed: 158 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -5,38 +5,182 @@
55
[![size](https://img.shields.io/bundlephobia/minzip/valtio-reactive)](https://bundlephobia.com/result?p=valtio-reactive)
66
[![discord](https://img.shields.io/discord/627656437971288081)](https://discord.gg/MrQdmzd)
77

8-
valtio-reactive makes Valtio a reactive library
8+
Reactive primitives for [valtio](https://github.com/pmndrs/valtio) — adds, `computed`, `effect`, and `batch` to enable fine-grained reactivity outside of React.
99

10-
## Background
10+
## Motivation
1111

12-
See: https://github.com/pmndrs/valtio/discussions/949
12+
`valtio`'s reactive capabilities are primarily designed for React via `useSnapshot` and only has limited support for computed values. `valtio-reactive` was made to fill those gaps while keeping `valtio` lean and fast.
1313

14-
## Install
14+
- Run side effects when specific properties change (not just any change)
15+
- Create derived/computed state that automatically updates
16+
- Batch multiple updates into a single reaction
17+
18+
See the [original discussion](https://github.com/pmndrs/valtio/discussions/949) for more context.
19+
20+
## Installation
1521

1622
```bash
1723
npm install valtio valtio-reactive
1824
```
1925

20-
## Usage
26+
## API
27+
28+
### `effect(fn, cleanup?): Dispose
29+
30+
This runs the first function (`fn`) immediately and re-runs it whenever any of the properties that are accessed in that function change. Only the properties are actually read during execution are tracked — changes to unread properties won't trigger re-runs. It returns a `dispose` function that will run the cleanup function when called.
31+
32+
```ts
33+
import { proxy } from 'valtio/vanilla';
34+
import { effect } from 'valtio-reactive';
35+
36+
const state = proxy({
37+
count: 0,
38+
unrelated: 'hello'
39+
user: {
40+
settings: {
41+
theme: 'light' //
42+
},
43+
name: 'Bob'
44+
},
45+
46+
})
47+
48+
const dispose = effect(
49+
() => {
50+
console.log('count is: ', state.count)
51+
console.log('theme is: ', state.user.settings.theme)
52+
},
53+
() => {
54+
// optional cleanup function
55+
console.log('cleaning up')
56+
}
57+
)
58+
// immediately logs:
59+
// "count is: 0"
60+
// "theme is: light'
61+
state.count++
62+
// logs:
63+
// "count is: 1"
64+
// "theme is: light"
65+
state.unrelated = 'world' // nothing happens when this property is changed because it wasn't accessed
66+
state.user.name = 'Robert' // nothing happens
67+
68+
state.user.settings.theme = 'dark'
69+
// logs:
70+
// "count is: 1"
71+
// "theme is: dark"
72+
73+
dispose()
74+
// logs "cleaning up"
75+
```
76+
77+
---
78+
79+
### `batch(fn): T`
80+
81+
Batches multiple state changes so that effects only react once after all changes complete. Returns the value returned by `fn`.
82+
83+
```ts
84+
import { proxy } from 'valtio/vanilla';
85+
import { batch, effect } from 'valtio-reactive';
86+
87+
const state = proxy({ count: 0 });
88+
89+
effect(() => {
90+
console.log('count:', state.count);
91+
});
92+
// Logs: "count: 0"
93+
94+
batch(() => {
95+
state.count++;
96+
state.count++;
97+
state.count++;
98+
});
99+
// Logs: "count: 3" (only once, not three times)
100+
```
101+
102+
---
103+
104+
### `computed(obj): T`
105+
106+
Creates a proxy object with computed/derived properties. Each property is defined as a getter function that automatically re-runs when its dependencies change.
21107

22-
```js
108+
```ts
23109
import { proxy } from 'valtio/vanilla';
24-
import { batch, computed, effect } from 'valtio-reactive';
110+
import { computed } from 'valtio-reactive';
25111

26112
const state = proxy({ count: 1 });
27113

28114
const derived = computed({
29115
double: () => state.count * 2,
116+
quadruple: () => state.count * 4,
30117
});
31118

119+
console.log(derived.double); // 2
120+
console.log(derived.quadruple); // 4
121+
122+
state.count = 5;
123+
124+
console.log(derived.double); // 10
125+
console.log(derived.quadruple); // 20
126+
```
127+
128+
The returned object is itself a `valtio` proxy, so you can use it with `effect`, `useSnapshot`, or any other `valtio` utility.
129+
130+
---
131+
132+
## Usage with React
133+
134+
While these primitives are framework-agnostic, they integrate seamlessly with `valtio`'s React bindings:
135+
136+
```tsx
137+
import { proxy, useSnapshot } from 'valtio';
138+
import { effect, computed } from 'valtio-reactive';
139+
140+
const state = proxy({ count: 0 });
141+
142+
// Computed values work with useSnapshot
143+
const derived = computed({
144+
double: () => state.count * 2,
145+
});
146+
147+
// Side effects outside of React
32148
effect(() => {
33-
console.log('double count:', derived.double);
149+
console.log('Count changed:', state.count);
34150
});
35151

36-
setInterval(() => {
37-
batch(() => {
38-
state.count++;
39-
state.count++;
40-
});
41-
}, 1000);
152+
function Counter() {
153+
const snap = useSnapshot(state);
154+
const derivedSnap = useSnapshot(derived);
155+
156+
return (
157+
<div>
158+
<p>Count: {snap.count}</p>
159+
<p>Double: {derivedSnap.double}</p>
160+
<button onClick={() => state.count++}>+1</button>
161+
</div>
162+
);
163+
}
42164
```
165+
166+
---
167+
168+
## TypeScript
169+
170+
All exports are fully typed. The `computed` function infers types from your getter functions:
171+
172+
```ts
173+
const state = proxy({ count: 1, name: 'test' });
174+
175+
const derived = computed({
176+
double: () => state.count * 2, // inferred as number
177+
message: () => `Hello ${state.name}`, // inferred as string
178+
});
179+
180+
derived.double; // number
181+
derived.message; // string
182+
```
183+
184+
## License
185+
186+
MIT

0 commit comments

Comments
 (0)