like-gold•19h ago
How to use a custom sidebar to filter data instead of provide navigation
Hello. I am a bit confused on how to sync table filter state when using a custom sidebar.
I want my sidebar to have table filters.
e.g App.tsx
<Route
element={
<ThemedLayout
Header={() => null}
Sider={() => <FilterSidebar />}
>
<TableProvider>
<Outlet />
</TableProvider>
</ThemedLayout>
}
>
list.tsx
const { tableProps, setFilters, filters } = useTable<IPost>({
resource: 'tasks',
queryOptions: {
enabled: true,
},
pagination: {
currentPage: 1,
pageSize: 5,
},
syncWithLocation: true,
})
FilterSidebar.tsx
const { tableProps, setFilters, filters } = useTable<IPost>({
resource: 'tasks',
queryOptions: {
enabled: false,
},
syncWithLocation: true,
})
// Trying to call setFilters via a button does not apply the filters on my table
// Despite that component rerendering but the url does get correctly updated with the filter
// and even after re-render filters from list.tsx is an empty []
// Is there a better way to share state in my app? I thought url updates would handle this
8 Replies
Hi @dashboard-dev-777. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave:
----------------------
Based on the knowledge sources, I can help clarify the issue you're experiencing with syncing filter state between your sidebar and table.
The Problem
The issue you're encountering is related to how
syncWithLocation works in refine. According to the documentation on syncWithLocation behavior, refine's syncWithLocation works in one direction only and only infers parameters at initial render to avoid syncing issues:
- When useTable is mounted with a routerProvider present, filters are inferred from query params
- Those values are stored in state within the useTable hook
- Changes in those states will update the query params
- However, if there are changes in query params not caused by that specific useTable instance, and those changes don't re-mount the hook, they are not synced with the internal states
This explains why your URL updates correctly when you call setFilters in your FilterSidebar, but the table in list.tsx doesn't reflect those changes - the useTable hook in list.tsx doesn't automatically react to URL changes after its initial mount.
Recommended Solution
The recommended workaround is to add an effect in your list.tsx to monitor URL parameter changes and manually sync them. Here's the approach suggested in the GitHub issue discussion:
Alternative Approach
Instead of using two separate useTable hooks, you could create a shared state management solution. As mentioned in a related discussion, you can create a custom hook to manage filter state that both components can access, though this would require manual handling of the filter logic.
The refine team has acknowledged that this behavior is confusing and has discussed implementing proper two-way binding for syncWithLocation, but it hasn't been prioritized yet.
----------------------
Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:
----------------------<@1438181786856460318> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
like-goldOP•19h ago
@kapa.ai What would the shared state management solution look like to solve this problem
Let me check the knowledge base for you again. One moment! :books:
----------------------
Based on the knowledge sources, I can provide some guidance on creating a shared state management solution, though the sources don't contain a complete implementation example.
Approach Using Context/Custom Hook
From the discussion about breaking filters into their own hook, a maintainer suggested that you can create a custom hook to keep your filter state. Here's the concept:
The maintainer noted: "You can actually create a custom hook to keep your filter state if you need to, that should work out of the box."
Practical Implementation Pattern
Based on the filtering examples in the useTable documentation, you could structure a shared solution like this:
TableProvider.tsx (your context):
list.tsx:
FilterSidebar.tsx:
Important Limitation
However, I should note that the knowledge sources don't provide a complete, tested implementation of this pattern. The sources primarily focus on using
syncWithLocation or the workaround with useParsed() that I mentioned in my previous response. The custom hook approach is mentioned as a possibility but without detailed implementation guidance.
----------------------
Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:
----------------------<@1438181786856460318> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
like-goldOP•19h ago
@kapa.ai Could mixing refine and jotai work well together to implement this
Let me check the knowledge base for you again. One moment! :books:
----------------------
Based on the knowledge sources, I can provide some insight into using Jotai with refine, though the sources don't contain specific implementation examples for your filtering use case.
Jotai Overview
According to the React Ecosystem article, Jotai is described as:
"a primitive and flexible state management library for React. It is built on top of React Hooks and the Context API. It takes an atomic approach to global React state management."The article shows that Jotai allows you to create atoms for managing state: Jotai is noted as being very lightweight with a bundle size of just 2.78kB and is used by companies like Adobe, TikTok, and Uniswap. Compatibility with Refine The knowledge sources confirm that Jotai is a legitimate state management solution in the React ecosystem, and since refine is a React-based framework with a headless architecture that decouples business logic from UI components, there's no inherent incompatibility mentioned. Important Limitation However, I must note that the knowledge sources do not contain any specific examples or documentation about integrating Jotai with refine's
useTable hook for managing filter state. While Jotai could theoretically be used to create shared atoms for your filter state that both your sidebar and table components could access, the sources don't provide implementation guidance or best practices for this specific scenario.
The sources primarily focus on refine's built-in state management through hooks like useTable and the syncWithLocation feature, along with the workaround using useParsed() that I mentioned in my previous response.
----------------------
Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:
----------------------<@1438181786856460318> Kapa.ai is still learning and improving, please let me know how I did by reacting below.