This guide helps you resolve common issues you might encounter when using @ibnlanre/portal.
| Problem | Possible Cause | Solution |
|---|---|---|
| Component not re-rendering after state change | Store not updated via $set() or updater from $use(). |
Ensure all state modifications use the store’s update mechanisms. |
Selector in $use(selector, deps) has incorrect dependencies. |
Verify the deps array for selectors in $use(). |
|
Using $get() in render path instead of $use(). |
Use $use() to subscribe React components to store changes. $get() does not subscribe. |
|
| Derived state not updating reactively | Using useMemo with incomplete dependencies. |
Include all store data in useMemo dependencies, or better yet, use $use() with a selector that depends on store state. |
| External variables captured in selector closure. | Rewrite selectors to depend on store state: store.$use(state => state.items.filter(item => item.ownedBy === state.selectedUserId)). |
|
| Array elements treated as stores | Attempting to call store methods on array elements. | Array elements are plain data. Use arrayStore.$get()[index].property instead of arrayStore[index].property.$get(). |
| State not persisting | Persistence adapter misconfigured (e.g., wrong key). | Double-check adapter configuration (key, stringify, parse). |
| Circular structures in state. | Use custom stringify/parse functions that handle circular references, or restructure data to avoid circularity. |
|
| Storage quota exceeded. | Monitor storage usage, implement cleanup strategies, or use compression for large states. | |
| Performance issues | Too many store subscriptions. | Use granular subscriptions, unsubscribe from unused stores, avoid unnecessary re-renders. |
| Large state objects causing slow updates. | Split large stores into smaller ones, use selectors for specific data needs. | |
| Type inference issues | Incorrect generic type parameters. | Explicitly provide type parameters to createStore<T>() when TypeScript can’t infer them correctly. |
| Complex nested types not properly inferred. | Use type assertions or break down complex types into simpler interfaces. | |
| Memory leaks | Forgotten subscriptions in components. | Always clean up subscriptions in React useEffect cleanup function or component unmount. |
| Multiple store instances created accidentally. | Create stores at the application level, not within components, unless specifically needed for component-local state. | |
| Type errors with store | Initial state type mismatch with usage. | Ensure the type of initialState matches how you intend to use the store. |
Incorrect type in $set() or action payload. |
Verify types for updates and action arguments. | |
| Asynchronous data not appearing in store | Accessing store before Promise in createStore(promise) resolves. |
await createStore(promise) or use $act()/$use() which will update when the promise resolves. |
| Promise rejected. | Add error handling for the promise passed to createStore or for the async operation that provides data for $set(). |
|
oldState is undefined in $act |
This is expected on the initial immediate call of the subscriber. | The first time a subscriber is called (if immediate is true or default), oldState will be undefined as there’s no “previous” state for that subscription yet. |
| Circular references causing issues | While supported, complex interactions might still be tricky. | Ensure normalizeObject is used if input objects are not plain data. Simplify state structure if possible. |
| Actions not updating state correctly | Using this context instead of store variable. |
In action functions, use the store variable (e.g., store.property.$set(value)) instead of this.property.$set(value). |
| Functions/symbols missing after normalization | normalizeObject() strips functions and symbol keys. |
This is expected behavior. Functions and symbol keys are filtered out. Handle them separately if needed. |
If you can’t find a solution to your issue here, please check our documentation or reach out to the community through our GitHub Issues page.