@@ -34,7 +34,6 @@ export function useRiveProperty<P extends ViewModelProperty, T>(
3434 Error | null ,
3535 P | undefined ,
3636] {
37- // Get the property first so we can read its initial value
3837 const property = useMemo ( ( ) => {
3938 if ( ! viewModelInstance ) return ;
4039 return options . getProperty (
@@ -43,17 +42,12 @@ export function useRiveProperty<P extends ViewModelProperty, T>(
4342 ) as unknown as ObservableViewModelProperty < T > ;
4443 } , [ options , viewModelInstance , path ] ) ;
4544
46- // Initialize state with property's current value (if available)
47- const [ value , setValue ] = useState < T | undefined > ( ( ) => property ?. value ) ;
45+ // Always start undefined — the listener delivers the current value as its first emission.
46+ // (iOS experimental: via valueStream; iOS/Android legacy: emitted synchronously on subscribe)
47+ // This ensures consumers handle the loading state correctly on all backends.
48+ const [ value , setValue ] = useState < T | undefined > ( undefined ) ;
4849 const [ error , setError ] = useState < Error | null > ( null ) ;
4950
50- // Sync value when property reference changes (path or instance changed)
51- useEffect ( ( ) => {
52- if ( property ) {
53- setValue ( property . value ) ;
54- }
55- } , [ property ] ) ;
56-
5751 // Clear error when path or instance changes
5852 useEffect ( ( ) => {
5953 setError ( null ) ;
@@ -86,22 +80,22 @@ export function useRiveProperty<P extends ViewModelProperty, T>(
8680 } ;
8781 } , [ options , property ] ) ;
8882
89- // Set the value of the property (no-op if property isn't available yet)
83+ // Set the value of the property (no-op if property isn't available yet).
84+ // Uses tracked `value` from state for updater functions — avoids a synchronous
85+ // property.value read and is consistent with how React state works.
9086 const setPropertyValue = useCallback (
9187 ( valueOrUpdater : T | ( ( prevValue : T | undefined ) => T ) ) => {
9288 if ( ! property ) {
9389 return ;
9490 } else {
9591 const newValue =
9692 typeof valueOrUpdater === 'function'
97- ? ( valueOrUpdater as ( prevValue : T | undefined ) => T ) (
98- property . value
99- )
93+ ? ( valueOrUpdater as ( prevValue : T | undefined ) => T ) ( value )
10094 : valueOrUpdater ;
10195 property . value = newValue ;
10296 }
10397 } ,
104- [ property ]
98+ [ property , value ]
10599 ) ;
106100
107101 return [ value , setPropertyValue , error , property as unknown as P ] ;
0 commit comments