Comments (4)
hey @simontreny any updates on this one? would be cool to see 2.x and also if you've considered react v18 concurrent mode + useSyncExternalStore ?
from micro-observables.
Hey, looks like we can work around this "in userspace", using the previous value we get in subscribe
!
import { observable, Observable } from 'micro-observables';
export type Equality<T> = (a: T, b: T) => boolean;
/**
* Takes an observable and produces a new one, which updates
* only if equals returns false.
* Example usage:
* const obs2 = sameIf(isEqual)(obs1)
**/
export function sameIf<T>(equals: Equality<T>) {
return (original: Observable<T>): Observable<T> => {
const derived = observable(original.get());
original.subscribe((newVal: T, oldVal: T) => {
if (!equals(newVal, oldVal)) {
derived.set(newVal);
}
});
return derived;
};
}
// or, if you prefer it as a constructor
export function observableMemo<T>(value: T, equals: Equality<T>): Observable<T> {
return sameIf(equals)(observable(value));
}
(sorry about the indents, github seems to mess them up no matter what i do)
codesandbox with some react code to check it out:
https://codesandbox.io/s/little-morning-jcq03u?file=/src/App.tsx
You'd still need to wrap everything with sameIf(myEquals)(...)
, but that's better than nothing i guess... or perhaps do something like this if you wanna save yourself some typing:
const selectIf = (equals) => (obs, selector) => sameIf(equals)(obs.select(selector))
Some alternative names: memoIf
, keepIf
, updateUnless
. The original one was memoIf
, but i feel like "memo" is a bit too general
from micro-observables.
This is something I am doing right now, but I am afraid that this solution is prone to memory leaks.
I assume that a regularly derived observable via .select()
can be garbage collected when the last reference to it is deleted.
Using the solution outlined by lubieowoce, by explicitly creating a subscription on the source observable and referencing the target observable, we bind the lifetime of the target observable to the source observable, and cannot simply "let it go".
I noticed that there is an undocumented Plugin architecture in the library that supports stuff like onAttach
etc.. so I think we might be able to make it memory safe using this, but since it's undocumented, kinda hard to say.
from micro-observables.
This is something I am doing right now, but I am afraid that this solution is prone to memory leaks.
I assume that a regularly derived observable via
.select()
can be garbage collected when the last reference to it is deleted.
Yes, you're right, deriving observables using subscribe()
will cause memory leaks as the source observables won't be garbage collected unless the unsubscribe function returned by subscribe()
is explicitly called.
I agree that equality function is definitely something that should be built-in directly in micro-observables. We actually already added support for it in the next major version of the library (that is not released yet). I've quickly tried to backport it into the 1.x version but unfortunately, this is not straightforward. The next version should hopefully be released in the next few weeks.
I noticed that there is an undocumented Plugin architecture in the library that supports stuff like onAttach etc.. so I think we might be able to make it memory safe using this, but since it's undocumented, kinda hard to say.
This API was an experiment to add support for persistence and dev tools to micro-observables
but we will drop it in 2.x in favor of another mechanism. Anyway I don't think it can be used to achieve what you want here.
from micro-observables.
Related Issues (14)
- Individual observables vs object HOT 2
- es6 proxies HOT 1
- using micro-observables library without react HOT 1
- useObservable forceRender race condition HOT 3
- react batching broken HOT 1
- "Cannot find module './lib'" ReactDOM Batching HOT 1
- Handling nested observable that is possibly undefined HOT 3
- Add ES module distribution HOT 1
- middleware HOT 2
- Observable.proxy idea HOT 2
- Including a dev tool
- React hook useObservable and SSR warnings HOT 1
- Add react-dom as an optional dependency HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from micro-observables.