@reactables/react 1.0.3 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/README.md +7 -141
  2. package/dist/index.js +9 -2
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -4,146 +4,12 @@
4
4
 
5
5
  Reactable bindings for React Components
6
6
 
7
- ## Table of Contents
7
+ [See docs at https://reactables.github.io/reactables/react/react-bindings/](https://reactables.github.io/reactables/react/react-bindings/)
8
8
 
9
- 1. [Installation](#installation)
10
- 1. [Providers](#providers)
11
- 1. [`StoreProvider`](#store-provider)
12
- 1. [Hooks](#hooks)
13
- 1. [`useReactable`](#use-reactable)
14
- 1. [`useAppStore`](#store-provider)
9
+ ### Contact
15
10
 
16
- ## Installation <a name="installation"></a>
17
-
18
- `npm i @reactables/react`
19
-
20
- ## Providers<a name="providers"></a>
21
-
22
- ### `StoreProvider`<a name="store-provider"></a>
23
-
24
- 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.
25
-
26
- **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.**
27
-
28
- Example:
29
- ```typescript
30
- // index.js
31
-
32
- import { storeValue, RxBuilder } from '@reactables/core';
33
- import React from 'react';
34
- import { createRoot } from 'react-dom/client';
35
-
36
- export interface AppState {
37
- userLoggedIn: boolean
38
- }
39
-
40
- export interface AppActions {
41
- logout: () => void;
42
- }
43
-
44
- const config = {
45
- name: 'rxAppStore',
46
- initialState: {
47
- userLoggedIn: false,
48
- },
49
- reducers: {
50
- loginSuccess: () => ({ userLoggedIn: true })
51
- logout: () => ({ userLoggedIn: false })
52
- }
53
- };
54
-
55
- const rxAppStore = storeValue(RxBuilder(config));
56
-
57
- const container = document.getElementById('root');
58
- const root = createRoot(container);
59
-
60
- root.render(
61
- <StoreProvider rxStore={rxAppStore}>
62
- <App />
63
- </StoreProvider>
64
- );
65
-
66
- ```
67
-
68
- ## Hooks<a name="hooks"></a>
69
-
70
- ### `useReactable` <a name="use-reactable"></a>
71
-
72
- 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`, and the original observable state `Observable<T>`.
73
-
74
- ```typescript
75
- export declare const useReactable: <T, S, U extends unknown[]>(
76
- reactableFactory: (...deps: U) => Reactable<T, S>, ...deps: U
77
- ) => [T, S, Observable<T>];
78
-
79
- ```
80
-
81
- Example:
82
-
83
- ```typescript
84
- import React from 'react';
85
- import { RxBuilder } from '@reactables/core';
86
- import { useReactable } from '@reactables/react';
87
-
88
- const RxToggle = (
89
- initialState = false,
90
- ) =>
91
- RxBuilder({
92
- initialState,
93
- name: 'rxToggle',
94
- reducers: {
95
- toggle: (state) => !state,
96
- },
97
- });
98
-
99
- const Toggle = () => {
100
- const [state, actions] = useReactable(RxToggle, false);
101
-
102
- if (!state) return;
103
-
104
- return (
105
- <div>
106
- <div>Toggle is: { state ? 'on' : 'off'} </div>
107
- <button type="button" onClick={actions.toggle}></button>
108
- </div>
109
- )
110
- }
111
-
112
- export default Toggle;
113
-
114
- ```
115
-
116
- ### `useAppStore`<a name="useAppStore"></a>
117
-
118
- React hook for accessing reactable provided by [`StoreProvider`](#store-provider) and binding it to a React component. Like [`useReactable`](use-reactable) it returns a tuple with the state `T`, actions `S`, and the original observable state `Observable<T>`.
119
-
120
- ```typescript
121
- export declare const useAppStore: <T, S = ActionMap>() => [T, S, Observable<T>];
122
- ```
123
-
124
- Example using the setup from [`StoreProvider`](#store-provider) example above:
125
-
126
- ```typescript
127
- import React from 'react';
128
- import { useAppStore } from '@reactables/react';
129
- import { AppState, AppActions } from '../index'
130
-
131
- const App = () => {
132
- const [appState, appActions] = useAppStore<AppState, AppActions>();
133
-
134
- if (!appState) return;
135
-
136
- return (
137
- <>
138
- <div>
139
- User is {appState.userLoggedIn ? 'logged in': 'not logged in'}.
140
- </div>
141
- <button type="button" onClick={appActions.logout}>Logout</button>
142
- </>
143
-
144
- )
145
- }
146
-
147
- export default App;
148
-
149
- ```
11
+ Dave Lai
12
+ email: <a href="dlai@dave-lai.com">dlai@dave-lai.com</a>
13
+ <br>
14
+ <br>
15
+ Github: https://github.com/laidav
package/dist/index.js CHANGED
@@ -25,8 +25,15 @@ var useReactable = function (reactableFactory) {
25
25
  var subscription = state$.subscribe(function (result) {
26
26
  setState(result);
27
27
  });
28
- var unsubscribe = subscription.unsubscribe.bind(subscription);
29
- return unsubscribe;
28
+ return function () {
29
+ // Adding setTimeout fixes the issue.
30
+ // React Strict Mode has bugs with clean up with refs so it breaks the useReactable hook as of now
31
+ // See Bug: https://github.com/facebook/react/issues/26315
32
+ // See Bug: https://github.com/facebook/react/issues/24670
33
+ setTimeout(function () {
34
+ subscription.unsubscribe();
35
+ }, 0);
36
+ };
30
37
  }, [state$]);
31
38
  return [state, actions, state$, messages$];
32
39
  };
package/package.json CHANGED
@@ -17,5 +17,5 @@
17
17
  "react": "^16.8.0 || ^17.0.0 || ^18.0.0",
18
18
  "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0"
19
19
  },
20
- "version": "1.0.3"
20
+ "version": "1.1.0"
21
21
  }