useStep()
A simple abstraction to play with a stepper, don't repeat yourself.
The Hook
1import { Dispatch, SetStateAction, useCallback, useMemo, useState } from 'react'23interface Helpers {4 goToNextStep: () => void5 goToPrevStep: () => void6 reset: () => void7 canGoToNextStep: boolean8 canGoToPrevStep: boolean9 setStep: Dispatch<SetStateAction<number>>10}1112type setStepCallbackType = (step: number | ((step: number) => number)) => void1314function useStep(maxStep: number): [number, Helpers] {15 const [currentStep, setCurrentStep] = useState(1)1617 const canGoToNextStep = useMemo(18 () => currentStep + 1 <= maxStep,19 [currentStep, maxStep],20 )2122 const canGoToPrevStep = useMemo(() => currentStep - 1 >= 1, [currentStep])2324 const setStep = useCallback<setStepCallbackType>(25 step => {26 // Allow value to be a function so we have the same API as useState27 const newStep = step instanceof Function ? step(currentStep) : step2829 if (newStep >= 1 && newStep <= maxStep) {30 setCurrentStep(newStep)31 return32 }3334 throw new Error('Step not valid')35 },36 [maxStep, currentStep],37 )3839 const goToNextStep = useCallback(() => {40 if (canGoToNextStep) {41 setCurrentStep(step => step + 1)42 }43 }, [canGoToNextStep])4445 const goToPrevStep = useCallback(() => {46 if (canGoToPrevStep) {47 setCurrentStep(step => step - 1)48 }49 }, [canGoToPrevStep])5051 const reset = useCallback(() => {52 setCurrentStep(1)53 }, [])5455 return [56 currentStep,57 {58 goToNextStep,59 goToPrevStep,60 canGoToNextStep,61 canGoToPrevStep,62 setStep,63 reset,64 },65 ]66}6768export default useStep
Usage
1import { useStep } from 'usehooks-ts'23export default function Component() {4 const [currentStep, helpers] = useStep(5)56 const {7 canGoToPrevStep,8 canGoToNextStep,9 goToNextStep,10 goToPrevStep,11 reset,12 setStep,13 } = helpers1415 return (16 <>17 <p>Current step is {currentStep}</p>18 <p>Can go to previous step {canGoToPrevStep ? 'yes' : 'no'}</p>19 <p>Can go to next step {canGoToNextStep ? 'yes' : 'no'}</p>20 <button onClick={goToNextStep}>Go to next step</button>21 <button onClick={goToPrevStep}>Go to previous step</button>22 <button onClick={reset}>Reset</button>23 <button onClick={() => setStep(3)}>Set to step 3</button>24 </>25 )26}
See a way to make this page better?
Edit there »