Skip to content

Commit

Permalink
fix: use useMutableCallback in useMainLoop
Browse files Browse the repository at this point in the history
  • Loading branch information
verekia committed Sep 10, 2024
1 parent 47fa6b7 commit 72b31cc
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 6 deletions.
16 changes: 13 additions & 3 deletions examples/react/src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { forwardRef, useImperativeHandle, useRef, useState } from 'react'
import { forwardRef, useEffect, useImperativeHandle, useRef, useState } from 'react'

import {
Listeners,
Expand Down Expand Up @@ -109,13 +109,23 @@ const UI = ({
const MainLoopThrottledRef = useRef<HTMLSpanElement>(null)
const [joystickMode, setJoystickMode] = useState<'follow' | 'origin'>('follow')

const [count, setCount] = useState(0)

useEffect(() => {
const interval = setInterval(() => {
setCount(count => count + 1)
}, 1000)

return () => clearInterval(interval)
}, [])

useMainLoop(({ elapsed }) => {
mainLoopRef.current!.textContent = String(Math.round(elapsed * 1000))
mainLoopRef.current!.textContent = `${String(Math.round(elapsed * 1000))} - Count: ${count}`
})

useMainLoop(
({ elapsed }) => {
MainLoopThrottledRef.current!.textContent = String(Math.round(elapsed * 1000))
MainLoopThrottledRef.current!.textContent = `${String(Math.round(elapsed * 1000))} - Count: ${count}`
},
{ throttle: 100 },
)
Expand Down
13 changes: 10 additions & 3 deletions packages/react/src/react-loops.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,17 @@
import { useEffect } from 'react'
import { useEffect, useRef } from 'react'

import { addMainLoopEffect } from '@manapotion/core'

import type { MainLoopEffectCallback, MainLoopEffectOptions } from '@manapotion/core'

import { useMutableCallback } from './util'

export const useMainLoop = (callback: MainLoopEffectCallback, options?: MainLoopEffectOptions) => {
// eslint-disable-next-line react-hooks/exhaustive-deps
useEffect(() => addMainLoopEffect(callback, options), [])
const mutableCallbackRef = useMutableCallback(callback)
const stableOptions = useRef(options)
useEffect(
() => addMainLoopEffect(args => mutableCallbackRef.current(args), stableOptions.current),
// eslint-disable-next-line react-hooks/exhaustive-deps
[],
)
}
15 changes: 15 additions & 0 deletions packages/react/src/util.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { useEffect, useLayoutEffect, useRef } from 'react'

// Borrowed from https://github.com/pmndrs/react-three-fiber/blob/master/packages/fiber/src/core/utils.ts

export const useIsomorphicLayoutEffect =
typeof window !== 'undefined' &&
(window.document?.createElement || window.navigator?.product === 'ReactNative')
? useLayoutEffect
: useEffect

export function useMutableCallback<T>(fn: T) {
const ref = useRef<T>(fn)
useIsomorphicLayoutEffect(() => void (ref.current = fn), [fn])
return ref
}

0 comments on commit 72b31cc

Please sign in to comment.