React Bindings
Reactable bindings for React Components
Installation
npm i @reactables/react
Providers
StoreProvider
Used to set up a context containing one reactable responsible for managing application (global) state. The reactable can be accessed via the useAppStore
hook in components.
Note: The reactable used for application state must be decorated with the storeValue
decorator to ensure subsequent subscriptions to the reactable by components receive the latest stored value.
Example:
// index.js
import { storeValue, RxBuilder } from '@reactables/core';
import React from 'react';
import { createRoot } from 'react-dom/client';
export interface AppState {
userLoggedIn: boolean
}
export interface AppActions {
logout: () => void;
}
const config = {
name: 'rxAppStore',
initialState: {
userLoggedIn: false,
},
reducers: {
loginSuccess: () => ({ userLoggedIn: true })
logout: () => ({ userLoggedIn: false })
}
};
const rxAppStore = storeValue(RxBuilder(config));
const container = document.getElementById('root');
const root = createRoot(container);
root.render(
<StoreProvider rxStore={rxAppStore}>
<App />
</StoreProvider>
);
Hooks
useReactable
React hook for binding a reactable to a React component. Accepts a reactable factory, dependencies (if any) and returns a tuple with the state T
, actions S
, the original observable state Observable<T>
, and optional actions observable.
export type HookedReactable<T, S> = [T, S, Observable<T>, Observable<Action<unknown>>?];
export declare const useReactable = <T, S, U extends unknown[]>(
reactableFactory: (...props: U) => Reactable<T, S>,
...props: U
) => HookedReactable<T, S>
Example:
import React from 'react';
import { RxBuilder } from '@reactables/core';
import { useReactable } from '@reactables/react';
const RxToggle = (
initialState = false,
) =>
RxBuilder({
initialState,
name: 'rxToggle',
reducers: {
toggle: (state) => !state,
},
});
const Toggle = () => {
const [state, actions] = useReactable(RxToggle, false);
if (!state) return;
return (
<div>
<div>Toggle is: { state ? 'on' : 'off'} </div>
<button type="button" onClick={actions.toggle}></button>
</div>
)
}
export default Toggle;
useAppStore
React hook for accessing reactable provided by StoreProvider
and binding it to a React component. Like useReactable
it returns a tuple with the state T
, actions S
, and the original observable state Observable<T>
.
export declare const useAppStore: <T, S = ActionMap>() => [T, S, Observable<T>];
Example using the setup from StoreProvider
example above:
import React from 'react';
import { useAppStore } from '@reactables/react';
import { AppState, AppActions } from '../index'
const App = () => {
const [appState, appActions] = useAppStore<AppState, AppActions>();
if (!appState) return;
return (
<>
<div>
User is {appState.userLoggedIn ? 'logged in': 'not logged in'}.
</div>
<button type="button" onClick={appActions.logout}>Logout</button>
</>
)
}
export default App;