pmndrs / react-spring

✌️ A spring physics based React animation library
http://www.react-spring.dev/
MIT License
28.23k stars 1.19k forks source link

[bug]: Incorrect result type in SpringValue `onChange` handler #2183

Open mattrossman opened 1 year ago

mattrossman commented 1 year ago

Which react-spring target are you using?

What version of react-spring are you using?

9.7.3

What's Wrong?

The onChange option in the SpringValue constructor indicates that the argument is of type AnimationResult<SpringValue<number>>

CleanShot 2023-08-03 at 13 48 53@2x

Thus, result.value is indicated to be of type number, and logging this should display the animated value. However, it actually prints undefined as the spring animates:

CleanShot 2023-08-03 at 13 49 39@2x

If I instead log the entire result, I see the number.

To Reproduce

import { SpringValue } from '@react-spring/web'

const spring = new SpringValue(0, {
 onChange(result) {
  console.log(result.value)
 }
})

spring.start(1)

Expected Behaviour

I expect to see the value on result.value, which TypeScript indicates is a number

Link to repo

https://codesandbox.io/s/vigorous-mirzakhani-qrrwj8?file=/src/App.tsx

Bilalshaikh15 commented 1 year ago

The onChange callback of the SpringValue is triggered whenever the animation state updates, which includes both the start and end states of the animation. However, at the start of the animation, the value property of the animation result might not have been set yet, leading to undefined being logged.

If you want to log the animated value specifically when it changes, you should use the onRest callback instead. The onRest callback is triggered when the animation completes and the final value is available. Here's an example of how you might modify your code:

const [spring] = useState(
    () =>
      new SpringValue(0, {
        onRest(result) {
          console.log(result.value);
        }
      })

so if you log result.value now the number 1 or 0 would be printed in the console.

Please let me know did i fix th issue, as i am new in contributing to open source can you tell me the project file location so i could commit changes.

mattrossman commented 1 year ago

Thank you for the suggestion. You're correct that within onRest, result contains and AnimationResult as expected. I'm specifically trying to use onChange here though, as I want to read intermediate values throughout the transition.

The reason my example is printing undefined is because result contains the actual value (a number) in the onChange callback instead of an AnimationResult type, and trying to read the "value" property from a number is undefined.

I can get the output I want by logging the result itself: https://codesandbox.io/s/busy-hugle-5w6px4?file=/src/App.tsx

The change I'm requesting is to ensure result holds an AnimationResult instead of a plain value to be consistent with the type signature and other callbacks.