Created
February 13, 2023 03:47
-
-
Save IrvingArmenta/b96f29cc7024350c7f62bc67b264bb69 to your computer and use it in GitHub Desktop.
useCycleState: hook for handling controlled queue states
This file contains hidden or 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 { useState } from 'react' | |
function useCycleState<T>(values: readonly T[]) { | |
const [currentIndex, setCurrentIndex] = useState(0) | |
const currentValue = values[currentIndex] as T | |
const nextAndPrev = (isPrev: boolean) => { | |
const valPlus = (currentIndex + 1) % values.length | |
let valMinus = (currentIndex - 1) % values.length | |
if (isPrev) { | |
return () => { | |
if (valMinus < 0) { | |
valMinus = values.length - 1 | |
} | |
setCurrentIndex(valMinus) | |
} | |
} else { | |
return () => { | |
setCurrentIndex(valPlus) | |
} | |
} | |
} | |
const setIndex = (newIndex: number) => { | |
if (newIndex === 0) { | |
if (import.meta.env.DEV) { | |
console.error( | |
'useCycleState:', | |
`0 is not allowed as a new index, use a number in this range: 1 ~ ${values.length}` | |
) | |
} | |
return | |
} | |
if (newIndex === 1) { | |
newIndex = 0 | |
} | |
if (values[newIndex]) { | |
setCurrentIndex(newIndex) | |
} else if (import.meta.env.DEV) { | |
console.error( | |
'useCycleState:', | |
`new index: ${newIndex} didn't return any value. make sure the newIndex number is in this range: 1 ~ ${values.length}` | |
) | |
} | |
} | |
return { | |
currentIndex: currentIndex + 1, | |
currentValue, | |
next: nextAndPrev(false), | |
prev: nextAndPrev(true), | |
setIndex, | |
} | |
} | |
export default useCycleState |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment