Skip to content

Commit a2b44cc

Browse files
committed
refactor: define _value via Object.defineProperty
1 parent fb69481 commit a2b44cc

File tree

1 file changed

+56
-40
lines changed

1 file changed

+56
-40
lines changed

packages/react-native-reanimated/src/mutables.ts

Lines changed: 56 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -23,22 +23,6 @@ export function makeMutableUI<Value>(initial: Value): Mutable<Value> {
2323
valueSetter(mutable, newValue);
2424
},
2525

26-
/**
27-
* _value prop should only be accessed by the valueSetter implementation
28-
* which may make the decision about updating the mutable value depending
29-
* on the provided new value. All other places should only attempt to modify
30-
* the mutable by assigning to value prop directly.
31-
*/
32-
get _value(): Value {
33-
return value;
34-
},
35-
set _value(newValue: Value) {
36-
value = newValue;
37-
listeners.forEach((listener) => {
38-
listener(newValue);
39-
});
40-
},
41-
4226
modify: (modifier, forceUpdate = true) => {
4327
valueSetter(
4428
mutable,
@@ -55,7 +39,28 @@ export function makeMutableUI<Value>(initial: Value): Mutable<Value> {
5539

5640
_animation: null,
5741
_isReanimatedSharedValue: true,
58-
};
42+
} as Mutable<Value>;
43+
44+
/*
45+
* _value prop should only be accessed by the valueSetter implementation
46+
* which may make the decision about updating the mutable value depending
47+
* on the provided new value. All other places should only attempt to modify
48+
* the mutable by assigning to value prop directly.
49+
*/
50+
Object.defineProperty(mutable, '_value', {
51+
get(): Value {
52+
return value;
53+
},
54+
set(newValue: Value) {
55+
value = newValue;
56+
listeners.forEach((listener) => {
57+
listener(newValue);
58+
});
59+
},
60+
configurable: false,
61+
enumerable: false,
62+
});
63+
5964
return mutable;
6065
}
6166

@@ -80,17 +85,6 @@ function makeMutableNative<Value>(initial: Value): Mutable<Value> {
8085
})();
8186
},
8287

83-
get _value(): Value {
84-
throw new Error(
85-
'[Reanimated] Reading from `_value` directly is only possible on the UI runtime. Perhaps you passed an Animated Style to a non-animated component?'
86-
);
87-
},
88-
set _value(_newValue: Value) {
89-
throw new Error(
90-
'[Reanimated] Setting `_value` directly is only possible on the UI runtime. Perhaps you want to assign to `value` instead?'
91-
);
92-
},
93-
9488
modify: (modifier, forceUpdate = true) => {
9589
runOnUI(() => {
9690
mutable.modify(modifier, forceUpdate);
@@ -108,7 +102,25 @@ function makeMutableNative<Value>(initial: Value): Mutable<Value> {
108102
},
109103

110104
_isReanimatedSharedValue: true,
111-
};
105+
} as Omit<Mutable<Value>, '_value'> as Mutable<Value>;
106+
107+
Object.defineProperty(mutable, '_value', {
108+
// This way of defining the property makes it hidden for
109+
// `Object.keys` etc. so if the user accidentally passes it
110+
// to React he won't get a critical error.
111+
get() {
112+
throw new Error(
113+
'[Reanimated] Reading from `_value` directly is only possible on the UI runtime. Perhaps you wanted to read from `value` instead?'
114+
);
115+
},
116+
set(_newValue: Value) {
117+
throw new Error(
118+
'[Reanimated] Setting `_value` directly is only possible on the UI runtime. Perhaps you wanted to assign to `value` instead?'
119+
);
120+
},
121+
configurable: false,
122+
enumerable: false,
123+
});
112124

113125
shareableMappingCache.set(mutable, handle);
114126
return mutable;
@@ -126,16 +138,6 @@ function makeMutableWeb<Value>(initial: Value): Mutable<Value> {
126138
valueSetter(mutable, newValue);
127139
},
128140

129-
get _value(): Value {
130-
return value;
131-
},
132-
set _value(newValue: Value) {
133-
value = newValue;
134-
listeners.forEach((listener) => {
135-
listener(newValue);
136-
});
137-
},
138-
139141
modify: (modifier, forceUpdate = true) => {
140142
valueSetter(
141143
mutable,
@@ -151,7 +153,21 @@ function makeMutableWeb<Value>(initial: Value): Mutable<Value> {
151153
},
152154

153155
_isReanimatedSharedValue: true,
154-
};
156+
} as Omit<Mutable<Value>, '_value'> as Mutable<Value>;
157+
158+
Object.defineProperty(mutable, '_value', {
159+
get(): Value {
160+
return value;
161+
},
162+
set(newValue: Value) {
163+
value = newValue;
164+
listeners.forEach((listener) => {
165+
listener(newValue);
166+
});
167+
},
168+
configurable: false,
169+
enumerable: false,
170+
});
155171

156172
return mutable;
157173
}

0 commit comments

Comments
 (0)