Skip to content

Commit cb307b9

Browse files
sammy-SCfacebook-github-bot
authored andcommitted
add synchronisation to Animated when used with setNativeProps (#43083)
Summary: Pull Request resolved: #43083 changelog: [internal] See code comments for details. Reviewed By: yungsters Differential Revision: D53818488 fbshipit-source-id: 71a1636a635c4c6599313b0c44be7215e9bdbcb5
1 parent 475a156 commit cb307b9

File tree

1 file changed

+20
-0
lines changed

1 file changed

+20
-0
lines changed

packages/react-native/Libraries/Animated/useAnimatedProps.js

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ export default function useAnimatedProps<TProps: {...}, TInstance>(
3737
): [ReducedProps<TProps>, CallbackRef<TInstance | null>] {
3838
const [, scheduleUpdate] = useReducer<number, void>(count => count + 1, 0);
3939
const onUpdateRef = useRef<?() => void>(null);
40+
const timerRef = useRef<TimeoutID | null>(null);
4041

4142
// TODO: Only invalidate `node` if animated props or `style` change. In the
4243
// previous implementation, we permitted `style` to override props with the
@@ -87,6 +88,25 @@ export default function useAnimatedProps<TProps: {...}, TInstance>(
8788
// $FlowIgnore[not-a-function] - Assume it's still a function.
8889
// $FlowFixMe[incompatible-use]
8990
instance.setNativeProps(node.__getAnimatedValue());
91+
if (isFabricInstance(instance)) {
92+
// Keeping state of Fiber tree and Shadow tree in sync.
93+
//
94+
// This is done by calling `scheduleUpdate` which will trigger a commit.
95+
// However, React commit is not fast enough to drive animations.
96+
// This is where setNativeProps comes in handy but the state between
97+
// Fiber tree and Shadow tree needs to be kept in sync.
98+
// The goal is to call `scheduleUpdate` as little as possible to maintain
99+
// performance but frequently enough to keep state in sync.
100+
// Debounce is set to 48ms, which is 3 * the duration of a frame.
101+
// 3 frames was the highest value where flickering state was not observed.
102+
if (timerRef.current != null) {
103+
clearTimeout(timerRef.current);
104+
}
105+
timerRef.current = setTimeout(() => {
106+
timerRef.current = null;
107+
scheduleUpdate();
108+
}, 48);
109+
}
90110
}
91111
};
92112

0 commit comments

Comments
 (0)