i try to two times set in selector (set)
first normal set
second delay set
but delay set not work
set(loadingState, {timeout: null, checkCount: 0})
import {atom, selector} from 'recoil'
const LOADING_MAX_TIME = 5000
const loadingState = atom({
key: 'loadingState',
default: {
checkCount: 0,
timeout: null,
},
})
const showLoadingSelect = selector({
key: 'showLoadingSelect',
set: ({set}) => {
set(loadingState, (prevState) => {
if (prevState.timeout) {
clearTimeout(prevState.timeout)
}
const timeout = setTimeout(() => {
// set is not work !!!!
set(loadingState, {timeout: null, checkCount: 0})
}, LOADING_MAX_TIME)
return {
checkCount: prevState.checkCount + 1,
timeout,
}
})
},
})
const hideLoadingSelect = selector({
key: 'hideLoadingSelect',
set: ({set}) => {
set(loadingState, (prevState) => ({
...prevState,
checkCount: prevState.checkCount - 1,
}))
},
})
const isLoadingSelect = selector({
key: 'isLoadingSelect',
get: ({get}) => {
const state = get(loadingState)
return state.checkCount > 0
},
})
export {showLoadingSelect, hideLoadingSelect, isLoadingSelect}
export default loadingState
This seems like something that's a better fit for useRecoilCallback.
Thanks @BenjaBobs! Yup, async sets are not allowed for selector set() method. useRecoilCallback() is the proper tool for this usecase.
Note the discussion in #762 for a feature request for async selector set, but the possible semantics for that might be for an async transaction and wouldn't apply to setTimeout().
Most helpful comment
This seems like something that's a better fit for useRecoilCallback.