@stevederico/skateboard-ui 2.9.7 → 2.9.8

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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # CHANGELOG
2
2
 
3
+ 2.9.8
4
+
5
+ Add useUser hook
6
+ Add useDispatch hook
7
+ Update README Context docs
8
+
3
9
  2.9.7
4
10
 
5
11
  Add useSafeNavigate hook
package/README.md CHANGED
@@ -770,7 +770,7 @@ import ErrorBoundary from '@stevederico/skateboard-ui/ErrorBoundary';
770
770
  ## Context (State Management)
771
771
 
772
772
  ```javascript
773
- import { getState } from '@stevederico/skateboard-ui/Context';
773
+ import { getState, useUser, useDispatch } from '@stevederico/skateboard-ui/Context';
774
774
 
775
775
  function MyComponent() {
776
776
  const { state, dispatch } = getState();
@@ -785,6 +785,33 @@ function MyComponent() {
785
785
  }
786
786
  ```
787
787
 
788
+ ### Optimized Hooks
789
+
790
+ Use these hooks to avoid unnecessary re-renders:
791
+
792
+ ```javascript
793
+ import { useUser, useDispatch } from '@stevederico/skateboard-ui/Context';
794
+
795
+ // Only re-renders when user changes (not on sidebar/theme changes)
796
+ function ProfileCard() {
797
+ const user = useUser();
798
+ if (!user) return null;
799
+ return <div>{user.name}</div>;
800
+ }
801
+
802
+ // Stable dispatch reference, never causes re-renders
803
+ function SignOutButton() {
804
+ const dispatch = useDispatch();
805
+ return <button onClick={() => dispatch({ type: 'CLEAR_USER' })}>Sign Out</button>;
806
+ }
807
+ ```
808
+
809
+ | Hook | Returns | Re-renders on |
810
+ |------|---------|---------------|
811
+ | `getState()` | `{ state, dispatch }` | Any state change |
812
+ | `useUser()` | `user` or `null` | User changes only |
813
+ | `useDispatch()` | `dispatch` | Never (stable) |
814
+
788
815
  ### State Shape
789
816
 
790
817
  ```javascript
package/core/Context.jsx CHANGED
@@ -206,3 +206,46 @@ export function ContextProvider({ children, constants }) {
206
206
  export function getState() {
207
207
  return useContext(context);
208
208
  }
209
+
210
+ /**
211
+ * Hook to access only the current user.
212
+ *
213
+ * More efficient than getState() when you only need user data,
214
+ * as it avoids re-renders from unrelated state changes.
215
+ *
216
+ * @returns {Object|null} Current user object or null if not authenticated
217
+ *
218
+ * @example
219
+ * import { useUser } from '@stevederico/skateboard-ui/Context';
220
+ *
221
+ * function ProfileCard() {
222
+ * const user = useUser();
223
+ * if (!user) return null;
224
+ * return <div>{user.name}</div>;
225
+ * }
226
+ */
227
+ export function useUser() {
228
+ const { state } = useContext(context);
229
+ return state.user;
230
+ }
231
+
232
+ /**
233
+ * Hook to access dispatch function.
234
+ *
235
+ * Use when you only need to dispatch actions without reading state.
236
+ * Avoids re-renders since dispatch is stable.
237
+ *
238
+ * @returns {Function} Dispatch function
239
+ *
240
+ * @example
241
+ * import { useDispatch } from '@stevederico/skateboard-ui/Context';
242
+ *
243
+ * function SignOutButton() {
244
+ * const dispatch = useDispatch();
245
+ * return <button onClick={() => dispatch({ type: 'CLEAR_USER' })}>Sign Out</button>;
246
+ * }
247
+ */
248
+ export function useDispatch() {
249
+ const { dispatch } = useContext(context);
250
+ return dispatch;
251
+ }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@stevederico/skateboard-ui",
3
3
  "private": false,
4
- "version": "2.9.7",
4
+ "version": "2.9.8",
5
5
  "type": "module",
6
6
  "exports": {
7
7
  "./Sidebar": {