I have a FilterContext provider and a hook useFilter in filtersContext.js:
import React, { useState, useEffect, useCallback } from 'react'
const FiltersContext = React.createContext({})
function FiltersProvider({ children }) {
const [filters, setFilters] = useState({})
return (
<FiltersContext.Provider
value={{
filters,
setFilters,
}}
>
{children}
</FiltersContext.Provider>
)
}
function useFilters(setPage) {
const context = React.useContext(FiltersContext)
if (context === undefined) {
throw new Error('useFilters must be used within a FiltersProvider')
}
const {
filters,
setFilters
} = context
useEffect(() => {
return () => {
console.log('reset the filters to an empty object')
setFilters({})
}
}, [setFilters])
{... do some additional stuff with filters if needed... not relevant }
return {
...context,
filtersForQuery: {
...filters
}
}
}
export { FiltersProvider, useFilters }
The App.js utilises the Provider as:
import React from 'react'
import { FiltersProvider } from '../filtersContext'
const App = React.memo(
({ children }) => {
...
...
return (
...
<FiltersProvider>
<RightSide flex={1} flexDirection={'column'}>
<Box flex={1}>
{children}
</Box>
</RightSide>
</FiltersProvider>
...
)
}
)
export default App
that is said, everything within FiltersProvider becomes the context of filters.
Now comes the problem description: I have selected on one page (Page1) the filter, but when I have to switch to another page (Page2), I need to flush the filters. This is done in the useFilters hook in the unmount using return in useEffect.
The problem is in the new page (Page2), during the first render I'm still getting the old values of filters, and than the GraphQL request is sent just after that. Afterwards the unmount of the hook happens and the second render of the new page (Page2) happens with set to empty object filters.
If anyone had a similar problem and had solved it?
first Page1.js:
const Page1 = () => {
....
const { filtersForQuery } = useFilters()
const { loading, error, data } = useQuery(GET_THINGS, {
variables: {
filter: filtersForQuery
}
})
....
}
second Page2.js:
const Page2 = () => {
....
const { filtersForQuery } = useFilters()
console.log('page 2')
const { loading, error, data } = useQuery(GET_THINGS, {
variables: {
filter: filtersForQuery
}
})
....
}
Printout after clicking from page 1 to page 2:
1. filters {isActive: {id: true}}
2. filters {isActive: {id: true}}
3. page 2
4. reset the filters to an empty object
5. 2 reset the filters to an empty object
6. filters {}
7. page 2