- Fix: The new undoRedo helper was not exported correctly, moved it to
/helpers
- Fix: IndexedDB plugin was not saving primitives properly when combined with
itemID
option
See https://www.legendapp.com/open-source/state/v3/other/migrating/ for details
- Types: Rewritten from scratch to be much better
- Feat: computed/proxy are now just functions
- Feat: New synced with much improved sync/persist functionality
- Feat: New sync plugins for Keel, Supabase, TanStack Query, fetch
- Removed: Old persist system, persistObservable, usePersistedObservable, etc...
- Change: useObservable with a function parameter is now reactive like useComputed was. So use peek() when accessing observables inside it if you want it to be just an initial value and not be reactive.
- Change: Computeds now only re-compute themselves when observed. This may cause some migration issues if your computeds had side effects, as they will not re-run when dependencies change unless being observed.
- Removed: lockObservable - With the new method of computeds it's not possible to modify the types to be readonly, so we removed this feature.
- Change: set and toggle return void: They had previously returned the observable in order to allow chaining, but it caused unintended side effects, so they now return void.
- Change:
onSet
was renamed toonAfterSet
for clarity - Removed: The concept of "after batch" - it was generally unreliable because batches can run recursively
- Renamed:
enableDirectAccess()
toenable$GetSet()
andenableDirectPeek()
toenable_PeekAssign()
for clarity
- Fix: Improved and better tested babel plugin - By @hzoo #270
- Fix: useSelector with an observable was ignoring suspense option - By @lishine #291
- Feat: An undoRedo helper to add undo/redo functionality to an observable
- Fix: Not persisting Map/Set correctly if at root of observable
- Fix: useSelector only short-circuits creating a hook if parameter is an observable, fixing useSelector re-rendering when its return value hadn't changed
- Fix: Recent useSelector optimizations causing some issuesin dev strict mode
- Fix: Types of observer
- Fix: useSelector was creating too many listeners
- Fix: array includes was not working correctly
- Fix: typescript errors when external imports are not available
- Fix: changed type imports from external packages to fail gracefully if they don't exist in node
- Fix: Dates were being considered as objects and were sometimes not being considered changed
- Fix: observe not running reaction if selector is an object or array
- Fix: An occasional error in sync get function
- Fix: Local cache was not saving Map/Set correctly
- Feat: usePauseProvider to pause/resume all updates under a context
- Feat: support persistence with no get
- Fix: errors in observer components getting swallowed
- Fix: persistence was not adding clearLocal to the new state node
- Fix: removed clearing ref from useObserve - it was causing fast refresh bugs and wasn't really necessary
- Package: Added react as an optional peerDependency
- Change: promise/persisted state key to support _state so it doesn't break user data with state keys, will slowly migrate to that
- Change: Setting a promise into an observable now creates a child prop
state
which is not in the raw data and is only accessible through the observable containing{ isLoaded, error }
- Change: Renamed some parameters in
persistObservable
andconfigureObservablePersistence
- Change:
afterBatch
removed and functionality merged intobatch
- Removed:
/react-components
exports - Removed:
enableLegendStateReact
- Removed:
eachValues
prop fromFor
- Deprecated:
enableReactDirectRender
- Deprecated: Reactive props ending in $ in favor of starting with $
- Docs: Brand new docs site at https://legendapp.com/open-source/state with better design, navigation sidebar, search
- Feat: Remote persistence with plugins for
fetch
, TanStack-Query, and Firebase Realtime Database - Feat:
enableReactTracking({ auto: true })
to make components automatically trackget()
calls on observables - Feat:
useWhen
anduseWhenReady
hooks - Feat:
computed
can be set or assigned into an observable after creation - Perf: Observable nodes activate lazily so creating or setting large objects is much faster
- Fix: Misc bugs with mergeIntoObservable
- Fix: Reactive.FlatList $data prop was not working
See https://legendapp.com/open-source/legend-state-v2/ for more details.
- Fix: computed was not activating if its value started as undefined
- Fix: useSelector was always re-rendering even if the returned value didn't change
- Removed the deprecation warning about reactive props since that might affect a lot of people and we can migrate that more slowly.
- This version displays deprecation warnings to prepare for version 2.0 release which will remove the deprecated features. See https://legendapp.com/open-source/state/migrating/ for details on migration or disabling the warning.
- Fix: Reactive elements were not supporting observable children
- Types: Improve types of useObservableQuery - By @bram209 #182
- Types: Types of Map and Set were not correct if at the root of an observable
- Fix:
size
property of Map was not an observable
- Feat:
proxy
supports three modes like computed: proxy to a computed plain object, proxy to an observable, proxy to a two-way computed - Feat:
proxy
sets raw values on parents and notifies when proxied children change - Fix: optimize batching so that modifying a child after modifying its parent merges into the existing change rather than creating a new change
- Fix:
Show
was not passing value to children when children is a function
- Feat: Nested computeds set their value on the raw object so that
get()
on the parent will include the values of child computeds
- Feat: Added findIDKey and optimized to internal
- Fix: Added more safety around dev-only assertions because they were throwing errors in some build systems
- Feat: Support Suspense with
useSelector(state, { suspend: true })
orstate.use({ suspend: true })
- Types: Improved types of proxy so it can have complex mapped types
- Fix: opaqueObject was not blocking looping through objects in constructor #163
Fix: the change to add SessionStorage was crashing when run server-side in Next.js
- Feat: Add
ObservablePersistSessionStorage
. -By @minorgod #164
- Types:
Selector
now allowsObservableEvent
- Types:
ObservableWriteable
was not exactly correct after the change to add Promise toset
- Fix:
useObservableNextRouter
was throwing warnings on some route changes - Fix:
enableDirectPeek
set now matches normal set behavior with promise and function extraction and all - Types: Package is now built in TypeScript strict mode
- Types: Improved types of Computed, Memo, and the babel transform
- Types: Improved handling of null and undefined in observables
- Types: Improve handling of optional properties in observable constructor
- Types: Add missing Promise type in set function
- Feat:
set
automatically unwraps promises
- Fix: Optional properties in observables were causing TS warnings
- Feat: add Reactive components, with configuration for React and React Native, to replace Legend components
- Fix: Improved types of useObservableQuery -By @sheldon-welinga #146
- Fix: babel transform was breaking Memo/Computed with observable child
- Feat: Returning an observable in a computed creates a two-way link to the target observable.
- Feat:
computed
is supported as a child of an observable - Feat:
proxy
is like acomputed
but given a key, usable by indexing into an object with a string key - Feat: Functions and computeds in the hierarchy of the constructing object in an observable are extracted into observable metadata so that setting the observable does not delete them.
- Feat:
Memo
andComputed
support observables as children - Feat:
reactiveComponents
makes multiple reactive components at once from the children of the target object - Feat: Reactive components and
reactive
makes children reactive if it's a functions - Fix:
useObserve
updates the compute and set functions when re-run - Fix: Direct setting with
_
was not working with falsy values - Change: Reactive props will now start with
$
instead of ending with$
. Both work for now, butprop$
will be deprecated in a later version. - Perf:
useSelector
skips creating a hook if it's inside anobserver
- Fix: Setting a primitive observable to the same value was still notifying listeners
- Fix: array.find was returning
[]
instead ofundefined
when it found no matches
- Feat: (experimental)
enableDirectPeek
enables a property on observables named _ as a shorthand for peek(), and assigning to it modifies the underlying object without notifying listeners of changes.
- Fix:
reactive
was not working with some external packages like NativeBase
See https://legendapp.com/open-source/state/experiments/ for details about the new features in this version.
- Feat: Ability to globally add functions/properties to observables
- Feat: (experimental)
enableDirectAccess
enables a property on observables named $ as a shorthand for get/set - Feat: (experimental)
enableReactUse
enables ause()
function on all observables to get the value of an observable and track it for changes within a React component - Feat: (experimental)
enableReactDirectRender
replacesenableLegendStateReact
(will be deprecated in a later version) - Fix:
afterBatch
was running after all recursive batches rather than just the current batch - Fix: Circular reference detection was failing on null values
- Fix: detection of circular references was having false positives if references existed in multiple places in the hierarchy
- Fix: Crash in proxy trap with nested calls to assign (part 2)
- Fix: Crash in proxy trap with nested calls to assign
- Perf: A small optimization in For to skip Object.assign if there's no itemProps
- Perf: Change merge of pending data on load to use setAtPath instead of mergeIntoObservable
- Misc: Add some warnings when setting an observable directly
- Fix: Remove peerDependencies which was causing issues in some environments
- Fix: Potential crash in persistence if pathTypes comes from persistence undefined
- Fix: _arr in fieldTransforms not working for strings
- Fix: peerDependencies to make next optional
- Types: Fix types of Switch so that it works better with booleans
- Types: Fix types of Map get so that it returns an Observable of the correct type
- Fix: When persisting, changes to a node are ignored if a later change modifies a parent node (as can happen when deleting nodes)
- Feat: Support Map in the For component
- Change: TrackingType "optimize" parameter is changed to a symbol to avoid conflict with Map get. It will still work for now, but please
import { optimize } from "@legendapp/state"
and use that instead. - Change: The For component's
eachValues
prop is deprecated in favor of just working with theeach
prop. It will still work for now, but please changeeachValues
toeach
.
- Feat: Added support for observable Map, WeakMap, Set, WeakSet
- Perf: Listeners are batched uniquely so that each listener will fire only once for all of the changes within a batch
- Change: Array filter and find return the observable instead of the raw data.
After an unexpectly large number of changes while in RC, 1.0 includes tons of improvements and fixes that can broadly be categorized as:
- Improved persistence plugin system
- Added two-way
computed
- Performance improvements
- A few minor breaking changes - see https://legendapp.com/open-source/state/migrating/
See https://legendapp.com/open-source/legend-state-v1/ for more details.
- Fix: Reactive FlatList
data$
prop was not working correctly #66
- Perf: Improve performance of arrays
- Perf: Improve performance of useSelector when passing an observable directly
- Perf: Improve performance of the For component
- Change:
useObserve
runs the function less often - Change:
when
checks truthiness instead of readiness. UsewhenReady
if you want empty objects and arrays to not count. - Change:
afterBatch
runs after the batch instead of at the end of a batch, which is more useful - Perf: Changes are internally batched by node instead of by listener, resulting in fewer
onChange
calls
- Feat: Add a sortValues function to For for use with eachValues
- Feat: Add support for a _keyExtractor field to return an arbitrary key value on arrays
- Change: internals is exported as an object instead of a separate export path
- Fix: Prevent batches from running recursively
- Fix: The second "reaction" paremeter in
observe
sometimes had an incorrectprevious
value
- Fix:
getPrevious()
in onChange was sometimes incorrect during a batch
- Perf: Removed IndexedDB preloader because it's actually slower because of the time it takes to copy the data across the Web Worker bridge
- Perf: Miscellaneous micro-optimizing
- Feat: Add a useObservableNextRouter hook for Next.js
- Perf: Persistence plugins queue into a microtask to bundle saves together
- Feat: Added
eachValues
prop to For to map the values of an object
- Fix: useSelector now uses useSyncExternalStore under the hood to support Suspense better
- Fix: mergeIntoObservable was sometimes deleting undefined fields
- Perf: Sped up IndexedDB plugin and removed the preloader because it was actually slower
- Fix: Fast Refresh sometimes resetting observables -By @GiFarina
- Perf: Running notifications in large objects sped up
- Fix:
afterBatch
was not working correctly if run from within a batch
- Feature: Added two way
computed
- Feature:
batch
has a newonComplete
batch(callback, onComplete)` parameter to run a function after the batch commits. This can be useful for cleaning up a temporary state while batching. - Fix: onChange with
initial
option fires immediately rather than going through batching process - Fix: Applying pending changes on load was writing back to local persistence unnecessarily
- Perf: Improve performance of
mergeIntoObservable
by just doing aset
if a target property is empty and doesn't need merging logic - Perf: Improve persistence overall by using more targeted approaches than
mergeIntoObservable
- Fix: Incrementing a value from 0 with a function (
value.set((prev) => prev + 1)
) was not firing a callback the first time
- Breaking:
onChange
function changed to take an options object as a second parameter with a newinitial
option that makes it fire immediately with the current value. - Breaking:
onChange
callback receives an object parameter instead of many arguments. This adds more flexibility for callers who care about different values in the change object. - Fix:
mergeIntoObservable
was not working correctly in some edge cases. - Fix: IndexedDB persistence improved for many edge cases, with some fixes and performance improvements
- Fix: Persistence layers overall improved with more stability and better performance
- Fix: Not notifying on change of dates
- Breaking: Improved the criteria of when to notify up parents for changes on objects to run only when something inside it has changed, so setting/assigning the same object onto itself will not notify. It's unlikely but possible that may be a breaking change for you if you depended on things re-computing/re-rendering even if nothing changed.
- Breaking: Removed automatically treating DOM nodes and React elements as opaque objects - it added most likely unnecessary extra code and is easily solved in a more generic way. If you're storing those in observables, wrap them in
opaqueObject(...)
. - Feature: Added
is*
functions to export - Perf: Batching was never clearing its safety timeouts, so thousands of changes at once could have been slow
- Breaking: Changed ignoreKeys to be an array to be easier to use
- Breaking: Remove the flexibility for saving arrays and basic objects (can do that with itemID now).
- Feature: IndexedDB supports adjustData, prefixID, itemID, fieldTransforms
- Fix: IndexedDB
loadTable
not being considered loaded if no data was available - Fix: Tons of miscellaneous IndexedDB fixes
- Fix: There was no way to subscribe to updates of dateModified
- Change: When returns the value directly, rather than a Promise, if it's already resolved on the first run
- Fix: mergeIntoObservable not working if source object has only symbol keys
- Fix: Not notifying on array change with the same length but ids added or removed
- Fix: IndexedDB preloader not loading correctly if it has to await the promise
- Fix: Changes deep in an object were not saving to IndexedDB correctly
- Fix: Metadata not saving properly from remote changes
- Breaking: Local Storage is no longer used as default persistence (to reduce build size for those not using it). Please configure persistence at the beginning of your application: https://legendapp.com/open-source/state/persistence/
- Breaking: Moved persist plugins to /persist-plugins export path
- Breaking: Internals of persistence plugins were changed to better support async loading and metadata. If you had made your own persistence plugin the changes should be straightforward, or create an Issue and we'll help migrate it.
- Breaking:
when
behavior tweaked to not be triggered by empty objects or empty arrays - Feature:
ObservablePersistIndexedDB
for persisting to IndexedDB - Fix:
useObserveEffect
not working right in React StrictMode - Types: Improved typing of
For
- Fix:
getObservableIndex
not working on index 0 - Fix:
useObserve
not working properly in StrictMode in React 18
- Fix:
useObservableQuery
was causing re-renders when using mutation
- Fix:
useObservableQuery
still not working right in StrictMode
- Fix:
useObservableQuery
not working in StrictMode
- Feat: Added
useObserveEffect
- Fix: Added useReducer overriding to
createObservableHook
- Feat: Added a
usePersistedObservable
hook - Feat: Added an optional second parameter to observe for an untracked callback function
- Feat: Added helpers:
pageHash
andpageHashParams
(replacesuseHash
) - Fix:
useObservableQuery
was sometimes not working because it was not loading the correct Context - Types: Improved types for strict mode
- Feat: For remote persistence plugins: Add options to disable local or remote sync, support loading remote even if there's no local
- Feat: Added useObservableQuery hook
- Feat: Added local persistence options, starting with mmkv configuration
- Change: Removed persist option from useObservable. It was a bad idea - it imported the whole /persist export. A better solution will come in an update soon.
- Fix:
createObservableHook
was not working with initialState as a function - Perf: Reduce number of renders by not notifying if setting with an unchanged object or array
- Fix: A circular import warning in the react export
- Fix:
useSelector
was not cleaning up when components when components re-rendered from a source other than observables - Types: Improved types for strict mode #56
- Feat: Added another way to use the
Switch
component, with multipleShow
children, that renders the firstShow
that matches - Types: Improved types for strict mode #52
- Feat: Added
opaqueObject
to make an element in an observable act as a primitive, not proxying its properties or notifying for changes. - Feat: Added some helpers:
observableFetch
,currentTime
,currentDay
- Feat: Added some hooks:
useFetch
,useHash
,useHover
,useIsMounted
,useMeasure
- Feat: Add
getObservableIndex
function to use with the observable argument toFor
- Fix:
reactive
was overriding the given function, causing problems if wrapping an external component and conditionally rendering the original component - Fix:
useObservableReducer
was not working with non-function arguments
- Fix: History not saving the initial object creation
- Fix: Crash when modifying an array was that included as initial value to an observable
- Fix: React Native Switch was not two-way binding properly
- Feat: Added a deps array to useComputed so it can be updated if dependencies change
- Feat: Added reactive types for SVGs
See https://legendapp.com/open-source/state/migrating for more details.
- Breaking: Changed observable
onChange
callback to take an array of changes rather than a single changed value because batched changes were only showing the most recently changed child value. - Breaking: Rename react-components export from legend to Legend
- Feat:
trackHistory
creates an observable that tracks a version history of a target observable - Feat: persistObservable caches pending changes offline so if they're not successfully saved remotely, it attempts to sync them after remote persistence is loaded
- Feat: Allow mergeIntoObservables to delete by using a symbol
- Fix: Types of React Native components were not supporting refs properly
- Fix: Reactive components not forwarding refs properly
- Fix: Tracing functions crashing if component is not an observer
- Fix: mergeIntoObservable was overwriting object children with undefined values
- Fix:
observer
was not auto-memoizing after the rewrite in 0.20.0 - Fix:
For
which a child function auto-observes
- Breaking: Changed behavior of
observe
anduseObserve
so that they have a callback parameter, useful for observing an event and doing something only when it changes. It also has a newprevious
parameter to compare to the previous run which depends on a return value, so the previous behavior using the return value is moved into the callback parameter. If you were returning false to cancel observing, you can now usee.cancel = true
. And if you were returning a cleanup function you can usee.onCleanup = () => ...
. It also adds anum
param to know how many times it's run. - Breaking: Renamed event
dispatch
tofire
- Breaking: Removed deprecated hooking into internal dispatcher
- Breaking: Removed deprecated Bindable components
- Feat: Added a callback parameter to
useObserve
, useful for observing an event and doing something only when it changes - Feat: Added useMount and useUnmount lifecycle hooks to encourage getting away from useEffect
- Feat:
useObserve
has a second callback parameter which will run after the selector. This can be useful for passing anobservable
orevent
as the first parameter. - Fix:
reactive
andobserve
components were sometimes not retaining their static properties (like id). They now use a Proxy wrapper instead of an HOC, which reduces component tree depth and avoids any other bugs from wrapping components and forwarding refs. - Fix:
event
was not working correctly in selectors - Fix: The two-way binding components are always controlled, even if the
value$
is undefined - Types: Improved types of
computed
anduseComponent
to accept a Promise
- Fix: Reactive components were sometimes not working in React Native #32
- Feat: Added
itemProps
toFor
component to pass extra props to items - Fix: Setter functions on primitives are auto-bound so you can pass them to event handlers
- Fix: Directly rendering primitive observables was erroring in getNode sometimes
- Feat: Observable booleans have a
toggle()
function - Perf: Observable primities are a simple function instead of a class, reducing code size and should be a bit faster
- Types: Improved typings of For component
- Fix: Persisting primitives
- Feat: Added
useObservableReducer
hook, which is the same asuseReducer
but it updates an observable rather than triggering a render #20
- Fix: Fast Refresh not disposing
observe()
correctly #25 - Fix: React hooks error in Show when toggling if it has a children function
- Types: Improved types of For to handle computed observables better
- Types: Improved types of useObservable to support Promises
- Feat:
createObservableHook
for converting other hooks that useuseState
to return an observable
- Feat: Support two-way binding multiple props, starting with checked$ on input
This is a big one, with a breaking change to stop observing all React components automatically. See https://legendapp.com/open-source/state/migrating for more details.
- Breaking: No longer observing all React components automatically. Please use
observer
oruseSelector
for observable tracking. - Breaking: Primitives no longer have
value
- use the standardget()
orset()
instead - Breaking: Removed
get(false)
in favor ofpeek()
- Deprecated: Bindable components will be phased out in favor of new reactive components. Import
{ legend }
on web or{ Legend }
on react-native instead of Bindable. - Feat: Added
observer
HOC component - Feat:
reactive
components that let you pass an observable or selector to any prop reactive-props - Feat:
useSelector
has options to control how often it renders and to reuse forceRender functions - Fix: Improved types for TypeScript strict mode
- Fix: Local storage persistence removes item if undefined
- Fix: Rendering multiple obseravbles inside one element had key collision issues
- Fix: Array move detection further improved
- Feat:
observe
function can return false to prevent tracking - Fix: Tracking was sometimes getting out of order with nested components and computed
- Fix: useSelector was triggering renders multiple times
- Fix: Array move detection was incorrect on inserts
- Fix: React-specific props were creating proxies unnecessarily
- Fix: Fast refresh issues with bindable components
- Fix: Fast refresh issues with direct rendering
- Fix: Rendering directly to JSX was not activating computeds
- Types: Improved typing of observable and useObservable to more correctly narrow down complex types
- Fix: Crash in Switch component in development
- Breaking: Renamed tracing functions to
use*
to match hook naming - Fix: Improved automatic React hooking into dispatcher to not need a
useEffect
and more dependably cleanup - Fix: Better handling JSX and DOM elements in observables
- Fix: Tracing functions were not always working correctly
- Fix: Errors building in Next.js
- Fix: Typing of Show component with Babel plugin enabled
- Feat: Support
computed
with a Promise
- Fix: React behavior disabled until it's activated by React rendering it
- Fix: Missing export of
useSelector
- Fix: Improve
observe()
disposing
- Fix: Undefined observables were not rendering directly in React properly
- Fix:
observe()
was not updating listeners on each run
- Fix: Typo in mergeIntoObservable
- Fix: Wrapped React hook injection in try/catch because it was sometimes causing errors like when hydrating in Next.js
This is a big one, with mainly a breaking change to how primitives work, so see https://legendapp.com/open-source/state/migrating for more details.
- Breaking: Primitives in state are now returned as observable objects like everything else, and you can use
get()
or.value
to access/modify the value - Breaking: Removed
obs()
function - Breaking:
set()
no longer has a keyed version because it's not needed now that we can dot through undefined nodes - Breaking: Renamed
useComputed
touseSelector
- Feature: Because primitives are returned as observables, we can now dot through undefined nodes
- Feature: Added
peek()
function, which is the same asget(false)
- Feature:
useComputed
returns acomputed
observable - Feature:
useObserve
creates anobserve
context - Feature:
computed
is now lazy and won't activate until its value is accessed for the first time - Feature:
Show
has awrap
prop to wrap children, for example with - Feature: Allow observable with no parameters, initialized to undefined
- Feature:
verifyNotTracking()
to make sure that components never re-render - Perf: Observables created as primitives use a class instead of a Proxy, to speed up the scenario of using tons of primitive observables
- Perf: Listeners that don't care about the value (like observe and React components) skip passing all the parameters to callbacks
- Fix: The new
enableLegendStateReact()
is more stable and works better with nested components - Fix: Rendering observables directly is more stable, especially in React Native
- Fix: Modifying listeners in an
observe
was sometimes causing infinite loops
- Fix: A component going from tracking nodes to not tracking nodes was causing errors
See https://legendapp.com/open-source/state/migrating for more details.
- Breaking: Removed
observer
HOC - Feat: No longer need
observer
HOC - CallenableLegendStateReact()
at the beginning of your app, and then all components automatically observe any accessed state - Feat:
when
callback receives the current value as the parameter - Feat: Add join to array functions that create shallow listeners
- Feat: Observables can easily switch back and forth between being an object or a primitive, and observable primitives have less overhead
- Fix: Crash when creating an observable starting undefined
- Fix: Assigning an object with function children
This is a big one with many breaking (but good) changes, so see https://legendapp.com/open-source/state/migrating for more details. We're making a lot of breaking changes all once so it's not too impactful.
- Breaking: There are now three levels of safety: Unsafe, Default, Safe. "Default" is new and allows direct assignment to primitives but prevents directly assigning to everything else. The previous default behavior was "Unsafe" so you may see errors if you were directly assigning to objects/arrays/etc... Replace those with
.set(...)
or pass infalse
as the second parameter toobservable
to go back to "Unsafe" mode. - Breaking: Renamed
ref()
toobs()
- Breaking: The array optimizations are now opt-in, because they can potentially have some unexpected behavior if modifying the DOM externally. You can enable them by using the
For
component with theoptimized
prop. - Breaking: Replaced
shallow
with aTracking
namespace, to add Optimized tracking. Changeshallow
toTracking.shallow
to get the previous behavior, orTracking.optimized
on an array to get the optimized behavior. - Breaking: Changed
observableBatcher
to export the batching functions directly instead of as a namespace - Breaking: Removed
onChangeShallow
,onTrue
,onEquals
, andonHasValue
in favor of the neweffect
andwhen
which automatically track any accessed observables. - Breaking: Renamed primitive observables' wrapping value from
current
tovalue
. - Breaking: Renamed
observableComputed
tocomputed
andobservableEvent
toevent
. - Breaking: Renamed the bindable components from
LS
toBindable
and they now export from '@legendapp/state/react-components' or '@legendapp/state/react-native-components' - Feat: Observable primitives can be rendered directly in React
- Feat: Added
observe
, which can run arbitrary code while tracking all accessed observables. - Feat: Added
when
, which can run functions when the predicate returns a truthy value. - Feat: Added
Switch
component - Feat: Support creating an observable with a Promise as a value, which will update itself when the promise resolves.
- Feat: A
lockObservable
function to prevent writes - Fix: Observables with arrays at the root were not notifying listeners properly
- Fix: Accessing
current
(nowvalue
) on a primitive observable was not tracking as expected - Fix: Improve types of Memo/Computed/Show components so that they require functions by default, and are expanded to not need functions when referencing the babel types.
- Feat: Allow passing observables directly to Show
- Fix: Usage of old observe() when if prop is an observable
- Fix: Some issues in remote persistence plugins (not yet released)
- Fix: Some issues in remote persistence plugins (not yet released)
- Fix: Old versions of React Native were crashing because of using
React.
without importing it
- Fix:
For
component with children re-renders with the latest children correctly
- Feature: A
For
component for easy rendering with array optimizations - Fix: Improve performance of observer
- Fix: Support
_id
or__id
field names for array optimizations - Fix: Mixing shallow and non-shallow listeners in a component could have not mixed correctly
- Types: Renamed exported types for improved clarity
- Fix: Exported components were losing className/style when not using bind prop
- Breaking Change: Removed observe() and prop(), favoring get() and ref(). get() tracks by default and ref() does not.
- Feat: Support ref to a path on an undefined value
- Fix: A crash when calling get() on an observable with undefined parents
- Types: Enforce bind prop to not be a primitive
- Types: Improved types of exported components
- Feat: Allow direct assignment, with warnings to catch accidental errors, and an optional "safe" mode
- Feat: input components with
bind
prop that automatically binds an observable to value and onChange - Feat: Support keyed ref:
obs.ref('key')
- Feat:
onChange
has arunImmediately
option - Fix:
.ref()
and.get()
inside anobserver
do reference counting so they don't untrack too aggressively - Fix:
delete()
was notifying listeners with the value undefined, but the key not yet deleted - Fix:
observer
was sometimes missing updates occurring between render and mount
- Fix: New set option with function parameter was breaking persistence
- Fix: Component useEffect was getting called before observer could listen for changes
- Fix: Babel plugin adds imports only once, only if not already imported
- Feat:
set()
can take a function to easily compute it relative to the previous value
- Feat: Added
traceListeners
andtraceUpdates
functions (exported from @legendapp/state/trace). Call them within an observer.traceListeners
logs the path of all tracked observables, whiletraceUpdates
logs details of each observable change that causes a render.
- Fix: observer was not working the first time in StrictMode
- Fix: observer was not cleaning up old listeners when the the tracked observables changed