Gathering detailed insights and metrics for @pago/reactive
Gathering detailed insights and metrics for @pago/reactive
Gathering detailed insights and metrics for @pago/reactive
Gathering detailed insights and metrics for @pago/reactive
npm install @pago/reactive
Typescript
Module System
Min. Node Version
Node Version
NPM Version
Cumulative downloads
Total Downloads
Last Day
0%
NaN
Compared to previous day
Last Week
0%
NaN
Compared to previous week
Last Month
0%
NaN
Compared to previous month
Last Year
0%
NaN
Compared to previous year
1
1
20
API Docs | CodeSandbox | Next.js Example | Examples
You are using React or Preact but find yourself frustrated by continuous bugs, errors or ceremony caused by the Hooks API? You thought you could avoid using a separate state management library like Redux, Recoil or MobX but started to run into unexpected performance issues with the Context API?
Then this library will eventually be the one for you! A reactive component model on top of React and Preact with automatic performance optimizations and a simple and predictable API that gets out of your way and supports you in achieving your goals. Blatantly copied from the fantastic Vue Composition API. But for React / Preact.
Huh? Eventually? Oh yes, this thing is bleeding cutting edge and likely to cause you all kinds of pain right now. Please don't use this in production. We are looking for feedback and observations from experiments you run. We fully expect to change major parts of the API in various different ways while we try to find the right set of primitives and abstractions to have a good balance between power and ease of learning.
If you would like to play around with the library:
We are roughly following planning to go through the following steps:
r
)inject
)fromHook
ref
values in Hooks components through useRefValue
r
? Can we adapt the JSX.Element['type']
property to include our kind of components?1/** @jsxImportSource @pago/reactive */ 2import { ref } from '@pago/reactive'; 3 4function Counter(props) { 5 const count = ref(0); 6 7 return () => ( 8 <div> 9 <div>Count: {count.current}</div> 10 <div> 11 <button type="button" onClick={() => (count.current += props.step)}> 12 Increment 13 </button> 14 <button type="button" onClick={() => (count.current -= props.step)}> 15 Decrement 16 </button> 17 </div> 18 </div> 19 ); 20}
1/** @jsxImportSource @pago/reactive */ 2import { r, ref, effect } from '@pago/reactive'; 3 4interface Props { 5 step: number; 6 delay: number; 7} 8 9function Timer(props: Props) { 10 const count = ref(0); 11 12 effect(onInvalidate => { 13 const timer = setInterval(() => { 14 // update is needed because we are reading from and writing to count 15 count.update(current => current + props.step); 16 }, props.delay); 17 18 onInvalidate(() => clearInterval(timer)); 19 }); 20 21 return r(() => ( 22 <div> 23 <div>Count: {count.current}</div> 24 </div> 25 )); 26}
The easiest way to setup @pago/reactive
for either React or Preact is to leverage the new jsxImportSource
option and to set it to @pago/reactive
.
Requirements:
Specifying @pago/reactive
as the JSX factory can be done using a comment at the beginning of the file. This should be supported by Babel & TypeScript.
1/** @jsxImportSource @pago/reactive */
As specified in the babel documentation:
1{ 2 "plugins": [ 3 [ 4 "@babel/plugin-transform-react-jsx", 5 { 6 "runtime": "automatic", 7 "importSource": "@pago/reactive" 8 } 9 ] 10 ] 11}
Not yet.
ref().current
instead of ref().value
?Because it allows us to do this:
1import { ref, effect } from '@pago/reactive'; 2 3function CounterComponent() { 4 const el = ref(); 5 effect(function updateDOMManually() { 6 el.current.innerHTML = 'Hello World'; 7 }); 8 return () => <div ref={el}></div>; 9}
When you try to use a component like the one below with TypeScript in JSX, it'll inform you that
() => Element
is not a valid type for a JSX Element.
1import { ref, effect } from '@pago/reactive'; 2 3function CounterComponent() { 4 const el = ref(); 5 effect(function updateDOMManually() { 6 el.current.innerHTML = 'Hello World'; 7 }); 8 return () => <div ref={el}></div>; 9}
For the time being we don't have a better solution than to use the provided r
function, which is basically
a type cast that fakes the right type to make TypeScript happy.
1import { r, ref, observe } from '@pago/reactive'; 2 3function CounterComponent() { 4 const el = ref(); 5 observe(function updateDOMManually() { 6 // `observe` is currently invoked immediately, rather than at the next tick 7 // not sure if that behaviour is better or worse than delaying it a bit 8 if (!el.current) return; 9 el.current.innerHTML = 'Hello World'; 10 }); 11 return r(() => <div ref={el}></div>); 12}
An alternative would be to use the wrap
function explicitly.
1import { wrap, ref, effect } from '@pago/reactive'; 2const CounterComponent = wrap(function CounterComponent() { 3 const el = ref(); 4 effect(function updateDOMManually() { 5 el.current.innerHTML = 'Hello World'; 6 }); 7 return () => <div ref={el}></div>; 8});
No vulnerabilities found.
No security vulnerabilities found.