Last active
April 27, 2020 12:06
-
-
Save kjellski/42ae99e7b1d85a76d835274c255c6af0 to your computer and use it in GitHub Desktop.
Workarround for `pollInterval` with `@apollo/react-hooks/useQuery`
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// NOTE: not using poll here because the interval needs to change on every call. | |
// So we're using multiple hooks to achieve this: | |
// 1. `useInterval` to keep the recalculation with `setVariablesIntervalCallback` triggering | |
// 2. `useState` to have a clear state change when we called `setVariablesIntervalCallback` | |
// 3. `usePrevious` to have data while new data is beeing fetched so the table can stay intact | |
const Container = ({ children, someValue }) => { | |
const [variables, setVariables] = useState({ | |
someValue, | |
value: calculateValue(), | |
}) | |
const setVariablesIntervalCallback = useCallback(() => { | |
setVariables(variables => ({ | |
...variables, | |
value: calculateValue(), | |
})) | |
}, [setVariables]) | |
useInterval(setVariablesIntervalCallback, POLL_INTERVAL_IN_MS) | |
const { data, loading, error } = useErrorHandlingQuery( | |
queryHubViewDashboard, | |
{ | |
skip: !hubId, | |
variables, | |
}, | |
) | |
const previousData = usePrevious(data) | |
return children({ | |
// we only want the last fetched data if there's no new one, this is helping while refetching to still fill the UI | |
data: data || previousData, | |
loading, | |
error, | |
}) | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { useRef, useEffect } from 'react' | |
/** | |
* A hook to repeatedly execute a `callback` after `intervalInMs` passed | |
* @param callback function to be executed | |
* @param intervalInMs interval to repeat the call at | |
* @returns {null} | |
*/ | |
export const useInterval = (callback, intervalInMs) => { | |
const savedCallback = useRef() | |
useEffect(() => { | |
savedCallback.current = callback | |
}, [callback]) | |
useEffect(() => { | |
if (intervalInMs) { | |
const handler = (...args) => savedCallback.current(...args) | |
const id = setInterval(handler, intervalInMs) | |
return () => { | |
if (id) { | |
clearInterval(id) | |
} | |
} | |
} | |
}, [callback, intervalInMs]) | |
return null | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { useEffect, useRef } from 'react' | |
/** | |
* A hook to have access to whatever the previous value was. | |
* For example: | |
* <pre> | |
* // State value and setter for our example | |
* const [count, setCount] = useState(0); | |
* | |
* // Get the previous value (was passed into hook on last render) | |
* const prevCount = usePrevious(count); | |
* | |
* // Display both current and previous count value | |
* return ( | |
* <div> | |
* <h1>Now: {count}, before: {prevCount}</h1> | |
* <button onClick={count => setCount(count + 1)}>Increment</button> | |
* </div> | |
* ); | |
* </pre> | |
* | |
* Also, see: | |
* <a href="https://usehooks.com/usePrevious/">https://usehooks.com/usePrevious</a> | |
* | |
* @param value | |
* @returns {*} previous value | |
*/ | |
export const usePrevious = value => { | |
// The ref object is a generic container whose current property is mutable ... | |
// ... and can hold any value, similar to an instance property on a class | |
const ref = useRef() | |
// Store current value in ref | |
useEffect(() => { | |
ref.current = value | |
}, [value]) // Only re-run if value changes | |
// Return previous value (happens before update in useEffect above) | |
return ref.current | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment