Skip to content

Commit 16e2d77

Browse files
mfazekasclaude
andauthored
fix: stabilize property setter functions by using global options & fix ci (#1)
* fix: stabilize property setter functions by using global options Property setter functions (setValue, setButtonText, etc.) from useRive* hooks were unstable because the options object was recreated on each render, even though useCallback was used for getProperty. This caused unnecessary re-renders and listener resets. Extract options to global constants to ensure stable object references across renders. For useRiveTrigger, use useMemo to recreate options only when onTrigger changes. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * fix(chore): ci - fix --------- Co-authored-by: Claude <noreply@anthropic.com>
1 parent 2a7691b commit 16e2d77

File tree

10 files changed

+85
-52
lines changed

10 files changed

+85
-52
lines changed

.github/workflows/ci.yml

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@ jobs:
2323
- name: Lint files
2424
run: yarn lint
2525

26+
- name: Codegen
27+
run: yarn nitrogen
28+
2629
- name: Typecheck files
2730
run: yarn typecheck
2831

@@ -47,6 +50,9 @@ jobs:
4750
- name: Setup
4851
uses: ./.github/actions/setup
4952

53+
- name: Build package
54+
run: yarn nitrogen
55+
5056
- name: Build package
5157
run: yarn prepare
5258

@@ -100,6 +106,10 @@ jobs:
100106
restore-keys: |
101107
${{ runner.os }}-gradle-
102108
109+
- name: Generate nitrogen code
110+
if: env.turbo_cache_hit != 1
111+
run: yarn nitrogen
112+
103113
- name: Build example for Android
104114
env:
105115
JAVA_OPTS: "-XX:MaxHeapSize=6g"
@@ -109,7 +119,7 @@ jobs:
109119
build-ios:
110120
runs-on: macos-latest
111121
env:
112-
XCODE_VERSION: 16.2
122+
XCODE_VERSION: 16.4
113123
TURBO_CACHE_DIR: .turbo/ios
114124
steps:
115125
- name: Checkout
@@ -154,6 +164,7 @@ jobs:
154164
- name: Install cocoapods
155165
if: env.turbo_cache_hit != 1 && steps.cocoapods-cache.outputs.cache-hit != 'true'
156166
run: |
167+
yarn nitrogen
157168
cd example
158169
bundle install
159170
bundle exec pod install --project-directory=ios

example/Gemfile

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@ source 'https://rubygems.org'
44
ruby ">= 2.6.10"
55

66
# Exclude problematic versions of cocoapods and activesupport that causes build failures.
7-
gem 'cocoapods', '>= 1.13', '!= 1.15.0', '!= 1.15.1'
7+
gem 'cocoapods', '>= 1.16'
88
gem 'activesupport', '>= 6.1.7.5', '!= 7.1.0'
9-
gem 'xcodeproj', '< 1.26.0'
9+
gem 'xcodeproj', '>= 1.27.0', '< 2.0'
1010
gem 'concurrent-ruby', '< 1.3.4'
1111

1212
# Ruby 3.4.0 has removed some libraries from the standard library.

example/Gemfile.lock

Lines changed: 32 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -5,26 +5,33 @@ GEM
55
base64
66
nkf
77
rexml
8-
activesupport (6.1.7.10)
8+
activesupport (7.1.5.2)
9+
base64
10+
benchmark (>= 0.3)
11+
bigdecimal
912
concurrent-ruby (~> 1.0, >= 1.0.2)
13+
connection_pool (>= 2.2.5)
14+
drb
1015
i18n (>= 1.6, < 2)
16+
logger (>= 1.4.2)
1117
minitest (>= 5.1)
18+
mutex_m
19+
securerandom (>= 0.3)
1220
tzinfo (~> 2.0)
13-
zeitwerk (~> 2.3)
1421
addressable (2.8.7)
1522
public_suffix (>= 2.0.2, < 7.0)
1623
algoliasearch (1.27.5)
1724
httpclient (~> 2.8, >= 2.8.3)
1825
json (>= 1.5.1)
1926
atomos (0.1.3)
20-
base64 (0.2.0)
21-
benchmark (0.4.0)
22-
bigdecimal (3.1.9)
27+
base64 (0.3.0)
28+
benchmark (0.5.0)
29+
bigdecimal (3.3.1)
2330
claide (1.1.0)
24-
cocoapods (1.15.2)
31+
cocoapods (1.16.2)
2532
addressable (~> 2.8)
2633
claide (>= 1.0.2, < 2.0)
27-
cocoapods-core (= 1.15.2)
34+
cocoapods-core (= 1.16.2)
2835
cocoapods-deintegrate (>= 1.0.3, < 2.0)
2936
cocoapods-downloader (>= 2.1, < 3.0)
3037
cocoapods-plugins (>= 1.0.0, < 2.0)
@@ -38,8 +45,8 @@ GEM
3845
molinillo (~> 0.8.0)
3946
nap (~> 1.0)
4047
ruby-macho (>= 2.3.0, < 3.0)
41-
xcodeproj (>= 1.23.0, < 2.0)
42-
cocoapods-core (1.15.2)
48+
xcodeproj (>= 1.27.0, < 2.0)
49+
cocoapods-core (1.16.2)
4350
activesupport (>= 5.0, < 8)
4451
addressable (~> 2.8)
4552
algoliasearch (~> 1.0)
@@ -60,8 +67,10 @@ GEM
6067
cocoapods-try (1.2.0)
6168
colored2 (3.1.2)
6269
concurrent-ruby (1.3.3)
70+
connection_pool (2.5.4)
71+
drb (2.2.3)
6372
escape (0.0.4)
64-
ethon (0.16.0)
73+
ethon (0.15.0)
6574
ffi (>= 1.15.0)
6675
ffi (1.17.2)
6776
fourflusher (2.3.1)
@@ -71,30 +80,30 @@ GEM
7180
mutex_m
7281
i18n (1.14.7)
7382
concurrent-ruby (~> 1.0)
74-
json (2.7.6)
83+
json (2.15.2)
7584
logger (1.7.0)
76-
minitest (5.25.4)
85+
minitest (5.26.0)
7786
molinillo (0.8.0)
7887
mutex_m (0.3.0)
79-
nanaimo (0.3.0)
88+
nanaimo (0.4.0)
8089
nap (1.1.0)
8190
netrc (0.11.0)
8291
nkf (0.2.0)
8392
public_suffix (4.0.7)
84-
rexml (3.4.1)
93+
rexml (3.4.4)
8594
ruby-macho (2.5.1)
86-
typhoeus (1.4.1)
87-
ethon (>= 0.9.0)
95+
securerandom (0.3.2)
96+
typhoeus (1.5.0)
97+
ethon (>= 0.9.0, < 0.16.0)
8898
tzinfo (2.0.6)
8999
concurrent-ruby (~> 1.0)
90-
xcodeproj (1.25.1)
100+
xcodeproj (1.27.0)
91101
CFPropertyList (>= 2.3.3, < 4.0)
92102
atomos (~> 0.1.3)
93103
claide (>= 1.0.2, < 2.0)
94104
colored2 (~> 3.1)
95-
nanaimo (~> 0.3.0)
105+
nanaimo (~> 0.4.0)
96106
rexml (>= 3.3.6, < 4.0)
97-
zeitwerk (2.6.18)
98107

99108
PLATFORMS
100109
ruby
@@ -103,14 +112,14 @@ DEPENDENCIES
103112
activesupport (>= 6.1.7.5, != 7.1.0)
104113
benchmark
105114
bigdecimal
106-
cocoapods (>= 1.13, != 1.15.1, != 1.15.0)
115+
cocoapods (>= 1.16)
107116
concurrent-ruby (< 1.3.4)
108117
logger
109118
mutex_m
110-
xcodeproj (< 1.26.0)
119+
xcodeproj (>= 1.27.0, < 2.0)
111120

112121
RUBY VERSION
113-
ruby 2.6.10p210
122+
ruby 2.7.8p225
114123

115124
BUNDLED WITH
116-
1.17.2
125+
2.4.22

example/ios/Podfile.lock

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2051,7 +2051,7 @@ SPEC CHECKSUMS:
20512051
glog: 5683914934d5b6e4240e497e0f4a3b42d1854183
20522052
hermes-engine: 314be5250afa5692b57b4dd1705959e1973a8ebe
20532053
NitroModules: 4e92fa5218beff179daf51714fd117e829027dd3
2054-
RCT-Folly: e78785aa9ba2ed998ea4151e314036f6c49e6d82
2054+
RCT-Folly: 36fe2295e44b10d831836cc0d1daec5f8abcf809
20552055
RCTDeprecation: 83ffb90c23ee5cea353bd32008a7bca100908f8c
20562056
RCTRequired: eb7c0aba998009f47a540bec9e9d69a54f68136e
20572057
RCTTypeSafety: 659ae318c09de0477fd27bbc9e140071c7ea5c93
@@ -2112,13 +2112,13 @@ SPEC CHECKSUMS:
21122112
React-timing: a90f4654cbda9c628614f9bee68967f1768bd6a5
21132113
React-utils: a612d50555b6f0f90c74b7d79954019ad47f5de6
21142114
ReactAppDependencyProvider: 04d5eb15eb46be6720e17a4a7fa92940a776e584
2115-
ReactCodegen: c63eda03ba1d94353fb97b031fc84f75a0d125ba
2115+
ReactCodegen: f37719863f9355a030dff77c98f59b7206333add
21162116
ReactCommon: 76d2dc87136d0a667678668b86f0fca0c16fdeb0
21172117
Rive: 273bc013df446eeaf8e9049a72033095ec339dde
21182118
RiveRuntime: 1e72d73bea430242387177b9d0aa95126406b462
21192119
RNGestureHandler: ebef699ea17e7c0006c1074e1e423ead60ce0121
21202120
SocketRocket: d4aabe649be1e368d1318fdf28a022d714d65748
2121-
Yoga: c758bfb934100bb4bf9cbaccb52557cee35e8bdf
2121+
Yoga: 9f110fc4b7aa538663cba3c14cbb1c335f43c13f
21222122

21232123
PODFILE CHECKSUM: 6974e58448067deb1048e3b4490e929f624eea3c
21242124

package.json

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@
3838
"typecheck": "tsc",
3939
"lint": "eslint \"**/*.{js,ts,tsx}\"",
4040
"clean": "del-cli android/build example/android/build example/android/app/build example/ios/build lib",
41-
"prepare": "bob build",
41+
"prepare": "yarn nitrogen && bob build",
4242
"nitrogen": "nitro-codegen",
4343
"release": "release-it",
4444
"dev:ios": "cd example && xed ios",
@@ -143,8 +143,7 @@
143143
[
144144
"custom",
145145
{
146-
"script": "nitrogen",
147-
"clean": "nitrogen/"
146+
"script": "nitrogen"
148147
}
149148
],
150149
[

src/hooks/useRiveBoolean.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,14 @@
1-
import { useCallback } from 'react';
21
import {
32
type ViewModelBooleanProperty,
43
type ViewModelInstance,
54
} from '../specs/ViewModel.nitro';
65
import type { UseRivePropertyResult } from '../types';
76
import { useRiveProperty } from './useRiveProperty';
87

8+
const BOOLEAN_PROPERTY_OPTIONS = {
9+
getProperty: (vmi: ViewModelInstance, p: string) => vmi.booleanProperty(p),
10+
};
11+
912
/**
1013
* Hook for interacting with boolean ViewModel instance properties.
1114
*
@@ -20,8 +23,6 @@ export function useRiveBoolean(
2023
const [value, setValue, error] = useRiveProperty<
2124
ViewModelBooleanProperty,
2225
boolean
23-
>(viewModelInstance, path, {
24-
getProperty: useCallback((vmi, p) => vmi.booleanProperty(p), []),
25-
});
26+
>(viewModelInstance, path, BOOLEAN_PROPERTY_OPTIONS);
2627
return { value, setValue, error };
2728
}

src/hooks/useRiveColor.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@ import { type UseRivePropertyResult } from '../types';
77
import { useRiveProperty } from './useRiveProperty';
88
import { RiveColor } from '../core/RiveColor';
99

10+
const COLOR_PROPERTY_OPTIONS = {
11+
getProperty: (vmi: ViewModelInstance, p: string) => vmi.colorProperty(p),
12+
};
13+
1014
/**
1115
* Hook for interacting with color ViewModel instance properties.
1216
*
@@ -23,9 +27,7 @@ export function useRiveColor(
2327
const [rawValue, setRawValue, error] = useRiveProperty<
2428
ViewModelColorProperty,
2529
number
26-
>(viewModelInstance, path, {
27-
getProperty: useCallback((vmi, p) => vmi.colorProperty(p), []),
28-
});
30+
>(viewModelInstance, path, COLOR_PROPERTY_OPTIONS);
2931

3032
const value =
3133
rawValue !== undefined ? RiveColor.fromInt(rawValue) : undefined;

src/hooks/useRiveNumber.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,14 @@
1-
import { useCallback } from 'react';
21
import {
32
type ViewModelInstance,
43
type ViewModelNumberProperty,
54
} from '../specs/ViewModel.nitro';
65
import type { UseRivePropertyResult } from '../types';
76
import { useRiveProperty } from './useRiveProperty';
87

8+
const NUMBER_PROPERTY_OPTIONS = {
9+
getProperty: (vmi: ViewModelInstance, p: string) => vmi.numberProperty(p),
10+
};
11+
912
/**
1013
* Hook for interacting with number ViewModel instance properties.
1114
*
@@ -20,8 +23,6 @@ export function useRiveNumber(
2023
const [value, setValue, error] = useRiveProperty<
2124
ViewModelNumberProperty,
2225
number
23-
>(viewModelInstance, path, {
24-
getProperty: useCallback((vmi, p) => vmi.numberProperty(p), []),
25-
});
26+
>(viewModelInstance, path, NUMBER_PROPERTY_OPTIONS);
2627
return { value, setValue, error };
2728
}

src/hooks/useRiveString.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,14 @@
1-
import { useCallback } from 'react';
21
import {
32
type ViewModelInstance,
43
type ViewModelStringProperty,
54
} from '../specs/ViewModel.nitro';
65
import type { UseRivePropertyResult } from '../types';
76
import { useRiveProperty } from './useRiveProperty';
87

8+
const STRING_PROPERTY_OPTIONS = {
9+
getProperty: (vmi: ViewModelInstance, p: string) => vmi.stringProperty(p),
10+
};
11+
912
/**
1013
* Hook for interacting with string ViewModel instance properties.
1114
*
@@ -20,8 +23,6 @@ export function useRiveString(
2023
const [value, setValue, error] = useRiveProperty<
2124
ViewModelStringProperty,
2225
string
23-
>(viewModelInstance, path, {
24-
getProperty: useCallback((vmi, p) => vmi.stringProperty(p), []),
25-
});
26+
>(viewModelInstance, path, STRING_PROPERTY_OPTIONS);
2627
return { value, setValue, error };
2728
}

src/hooks/useRiveTrigger.ts

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { useCallback } from 'react';
1+
import { useCallback, useMemo } from 'react';
22
import {
33
type ViewModelInstance,
44
type ViewModelTriggerProperty,
@@ -9,6 +9,9 @@ import type {
99
} from '../types';
1010
import { useRiveProperty } from './useRiveProperty';
1111

12+
const getTriggerProperty = (vmi: ViewModelInstance, p: string) =>
13+
vmi.triggerProperty(p);
14+
1215
/**
1316
* Hook for interacting with trigger ViewModel instance properties.
1417
*
@@ -22,13 +25,19 @@ export function useRiveTrigger(
2225
params?: UseViewModelInstanceTriggerParameters
2326
): UseRiveTriggerResult {
2427
const { onTrigger } = params ?? {};
28+
29+
const triggerOptions = useMemo(
30+
() => ({
31+
getProperty: getTriggerProperty,
32+
onPropertyEventOverride: onTrigger,
33+
}),
34+
[onTrigger]
35+
);
36+
2537
const [_, __, error, property] = useRiveProperty<
2638
ViewModelTriggerProperty,
2739
undefined
28-
>(viewModelInstance, path, {
29-
getProperty: useCallback((vmi, p) => vmi.triggerProperty(p), []),
30-
onPropertyEventOverride: onTrigger,
31-
});
40+
>(viewModelInstance, path, triggerOptions);
3241

3342
const trigger = useCallback(() => {
3443
if (property) {

0 commit comments

Comments
 (0)