External Access
As of v7.0.0
The context, once created, has a store property which is accessible from any where whether within the react component tree or in a native runtime environment.
How do I access the store externally?
This is done by simply utilizing the context
store property.For external access to the context, 4 store methods have been exposed. Namely:
store.getState(): Provides a static snapshot of the current state. Since v6.0.0, may accept a list of property paths to target properties within the state to fetch and returnstore.resetState(): Please see descriptions in the store page. Since v6.0.0, may accept a parameterless invocation resulting in a noop.store.setState(): Please see descriptions in the store page.store.subscribe(...)- Provides the API for manual subscription to the context's change and close events. - Returns a parameterless void function - the unsubcriber. - Accepts a "closing" event type and an observer function to be called before context deactivation. - Accepts a "data-updated" event type and an observer function for state changes. store.subscribe( 'data-updated', ( changes : Changes<State>, changedPaths : Array<Array<string>>, netChanges : Partial<State>, mayHaveChangesAt : (tokenizedPath : string[]) => boolean ) => void ); // => VoidFunction"data-updated" event listener params- changes: an object or array holding the original change request payload(s).
- changedPaths: an array of tokenized property paths belonging to state properties changed during this request.
- netChanges: an object of the final state of all properties in state changed.
- mayHaveChangesAt: a function to confirm that a given property path is among the new changes. This path is to be supplied as a tokenized string (i.e. supply
['a', 'b', 'c', '0', 'r']for'a.b.c[0].r').
Let's see some code!
Sharing the store with a class.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
import React, { useCallback, useEffect, useRef, useState } from 'react';
import ObservableContext from './context'; // using example from the "Getting Started Page"
import Ui from './ui'; // using example from the "Getting Started Page"
import StoreMonitor from './debug-monitor';
const App = () => {
const [ monitor ] = useState(() => new StoreMonitor(
d => console.log( d ),
ObservableContext.store
));
useEffect(() => {})
useEffect(() => () => monitor.cleanup(), []);
return ( <Ui /> );
}
export default App;Using a simple class instance to montor and report changes in the store in realtime.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
class Monitor {
private _onEvent;
private _store;
private _unsub;
constructor( onEvent, store ) {
this._onEvent = onEvent;
this._source = store;
}
set onEvent( handler ) { this._onEvent = handler }
get source() { return this._store }
set source( store ) {
if( store === this._store ) { return }
this.cleanup();
if( !store ) { return }
this._store = store;
this._onEvent( this._store.getState() );
this._unsub = store.subscribe(
() => this._onEvent( this._store.getState() )
);
}
cleanup() {
this._unsub?.();
this._store = null;
}
}
export default Monitor;State references are always snapshots of the state at the time of access. In essence, the state returned by
context.store.getState(...) are not affected by subsequent updates to the store's state. Any updates to this acquired state never affects the context's state. So therefore, the 4 considerations:use only the
context.store.setState(...) to update the context internal store.context.store.getState(...) must be used to obtain the current state value.use your
context.store.subscribe(...) to manually subscribe to state changes and refresh your current state value in realtime.use the
unsubscriber returned by your context store's subscribe(...) to unsubscribe from the store when needed.