Update state doesn't work in hook
Unanswered
Barbado da Terceira posted this in #help-forum
Barbado da TerceiraOP
Hello everyone,
I'm trying to implement a hook called useCarousel to have a carousel in an easy way without adding too much logic/animations to my components.
The problem is that I've encountered many "bugs" with the state, because it doesn't update !
I use several useEffect and useCallback in my code, but I'm sure that I've implemented them properly so they should be working !
You can have a simple example with the handleDrag function, triggered from the onDrag parameter in my Draggable options.
Originally, my direction state is 0, I update the state with setDirection to "ok" just to see any difference, but nothing, still getting 0 in the console.log.
Anyone have an idea of what's causing this ?
I'm trying to implement a hook called useCarousel to have a carousel in an easy way without adding too much logic/animations to my components.
The problem is that I've encountered many "bugs" with the state, because it doesn't update !
I use several useEffect and useCallback in my code, but I'm sure that I've implemented them properly so they should be working !
You can have a simple example with the handleDrag function, triggered from the onDrag parameter in my Draggable options.
Originally, my direction state is 0, I update the state with setDirection to "ok" just to see any difference, but nothing, still getting 0 in the console.log.
Anyone have an idea of what's causing this ?
1 Reply
Barbado da TerceiraOP
const useCarousel = (elementRef: React.RefObject<HTMLElement>, options: Draggable.Vars = {}) => {
const [draggable, setDraggable] = useState<Draggable | null>(null)
const [snapPoints, setSnapPoints] = useState<number[]>([])
const [direction, setDirection] = useState<any>(0)
const [slides, setSlides] = useState<Array<any>>([])
const [currentSlide, setCurrentSlide] = useState<number>(0)
useEffect(() => initCarousel(), [elementRef])
useEffect(() => getSnapPoints(), [slides])
useEffect(() => initDraggable(), [snapPoints])
const handleSnapX = useCallback(() => {
// ...
}, [...])
const handleDrag = useCallback(
(d: any) => {
setDirection('ok')
console.log(direction)
},
[draggable, setDirection, direction]
)
const getSnapPoints = useCallback(() => {
// ...
}, [...])
const draggableOptions: Draggable.Vars = useMemo(() => {
return {
...options,
type: 'x',
bounds: {
minX: snapPoints[slides.length - 1],
maxX: 0,
},
maxDuration: 0.6,
minDuration: 0.3,
inertia: true,
snap: {
x: () => handleSnapX(),
},
onDrag: function () {
handleDrag(this)
},
}
}, [draggable, snapPoints, slides.length, options, handleSnapX, handleDrag])
const initCarousel = () => {
const haveElement = Boolean(elementRef.current)
if (!haveElement) return
setSlides(Array.from(elementRef.current!.children))
getSnapPoints()
window.addEventListener('resize', getSnapPoints)
return () => {
window.removeEventListener('resize', getSnapPoints)
}
}
const initDraggable = () => {
const haveSnapPoints = Boolean(snapPoints.length)
const haveSlides = Boolean(slides.length)
if (!haveSnapPoints || !haveSlides) return
const d = Draggable.create(elementRef.current, draggableOptions)
setDraggable(d[0])
}
return draggable
}
export default useCarousel