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.