question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

useAnimatedStyle does not re-render when sharedValue changes

See original GitHub issue

Description

I am trying to create spotify kind of scroll view, where the list items are going on top of the first sticky item, then the first sticky item will go blurry on scroll. I implemented it in the native Animated RN API, and now want to convert it to reanimated. However I can’t seem to make the animation re-render on scroll.

this is the overall component:


  const scrollOffSet = useSharedValue(0);
  const scrollHandler = useAnimatedScrollHandler({
    onScroll: (event) => {
      scrollOffSet.value = event.contentOffset.y;
    },
  });
  const headerAnimatedStyle = useAnimatedStyle(() => {
    const result = {
      opacity: interpolate(scrollOffSet.value, [0, 80], [1, 0], Extrapolate.CLAMP),
      transform: [
        {
          scale: interpolate(scrollOffSet.value, [0, -80], [1, 2], Extrapolate.CLAMP),
        },
      ],
    };
    return result;
  });



return (
         <Animated.ScrollView
            stickyHeaderIndices={[0]}
            showsVerticalScrollIndicator={false}
            contentContainerStyle={[s.mt0, s.pt0]}
            style={s.bg_white}
            onScroll={scrollHandler}
            scrollEventThrottle={16}
          >
            <Animated.View
              style={[s.bg_white, s.flx_i, { zIndex: 50 }, headerAnimatedStyle]}
            >
              <View style={s.ph3}>
                <ProfileHeaderV2 />
              </View>
            </Animated.View>

            {/* unanimated scrollable items go here*/}
            <View style={[{ zIndex: 1000 }, s.bg_white]}>
            </View>
         </Animated.ScrollView>
 );

Expected behavior

On scroll, first item should go blurry, until the opacity is gone

Actual behavior & steps to reproduce

Doesn’t re-render at all. however if i scroll a bit, then save the code (force to re-render), the style applies. Am i allowed to have nested Animated.View in Animated.ScrollView? I’m not sure why this is not working.

also when i put console.log in scrollHandler, it is applying the scroll offset value on scroll. it’s just that the useAnimatedStyle is not re-rendering

i’m on iOS simulator iphone 13

Package versions

    "react-native": "^0.65.0-0",
    "react-native-reanimated": "^2.3.1",
  • NodeJS: v16

Issue Analytics

  • State:open
  • Created 2 years ago
  • Comments:10 (1 by maintainers)

github_iconTop GitHub Comments

7reactions
chinhfyb12commented, Jun 24, 2022

@robertwt7 you should add dependencies like this. it’s work! Screen Shot 2022-06-24 at 17 34 40

4reactions
MehmetKaplancommented, Jun 26, 2022

I am not sure if the cases are the same or not but I had a case with similar symptoms for the useAnimatedStyle. But my case does not have the useSharedValue functionality.

Logging the animated style, I observed viewDescriptors fields waitForInsertSync, sharableViewDescriptors, items are changing in the steps. My conclusion is Reanimated can be mutating the same object, which is not caught by the react as a re-render change. The log steps:

STEP-1:  {"viewDescriptors":{"batchToRemove":{},"tags":{},"waitForInsertSync":false,"waitForRemoveSync":false,"sharableViewDescriptors":{"value":[]},"items":[]},"initial":{"value":{"height":57.875,"width":57.875,"borderRadius":8.94217927472446}},"viewsRef":{"items":{}}}

STEP-2:  {"viewDescriptors":{"batchToRemove":{},"tags":{},"waitForInsertSync":false,"waitForRemoveSync":false,"sharableViewDescriptors":{"value":[]},"items":[]},"initial":{"value":{"height":57.875,"width":57.875,"borderRadius":8.94217927472446}},"viewsRef":{"items":{}}}

STEP-3:  {"viewDescriptors":{"batchToRemove":{},"tags":{},"waitForInsertSync":true,"waitForRemoveSync":false,"sharableViewDescriptors":{"value":[]},"items":[{"tag":43,"name":"RCTView"}]},"initial":{"value":{"height":57.875,"width":57.875,"borderRadius":8.94217927472446}},"viewsRef":{"items":{}}}

STEP-4:  {"viewDescriptors":{"batchToRemove":{},"tags":{},"waitForInsertSync":false,"waitForRemoveSync":false,"sharableViewDescriptors":{"value":[{"tag":43,"name":"RCTView"}]},"items":[{"tag":43,"name":"RCTView"}]},"initial":{"value":{"height":57.875,"width":57.875,"borderRadius":8.94217927472446}},"viewsRef":{"items":{}}}

My workaround

For my case I was lucky since I have no strict performance handicaps so I implemented following workaround. I introduced a new state variable, rerender and used it to signal react to re-render. But let me emphasize, if you will use this you’ll want to consider performance impact.

...
const [rerender, setRerender] = React.useState(0);
function incrementRerender() {
	let nextVal = rerender + 1;
	setRerender(nextVal);
}
...
const animatedStyles = useAnimatedStyle(() => {
	runOnJS(incrementRerender)(); // <<<<<<-----  Injected to signal react to re-render. (WORKAROUND)
	return {
		height: props.height,
		width: props.width,
		borderRadius: props.borderRadius,
	}
}, [props.height, props.width, props.borderRadius]);
...
return <PanGestureHandler
	rerender={rerender}
	onGestureEvent={gestureHandler}
	maxPointers={1}
	minDist={10}
>
	<Animated.View style={[constantStyles.tile, animatedStyles, animatedTransformStyles]}>
		{props.children}
	</Animated.View>
</PanGestureHandler>
Read more comments on GitHub >

github_iconTop Results From Across the Web

useAnimatedStyle | React Native Reanimated
In the above example, the used shared value is not changing, hence there is no real benefit of using an animated style there....
Read more >
Set value immediately after another one have been set in ...
I am using a shared value to animate a View as we all know setting the value of the shared value will automatically...
Read more >
Shared Values - React Native Reanimated
Shared Values are among the fundamental concepts behind Reanimated 2.0. ... the worklet will re-run upon the Shared Value change. ... useAnimatedStyle,
Read more >
How to use Reanimated 2 (a beginners guide)
But when we press the image nothing is happening... why? It's not changing because, unlike when calling setState , it doesn't cause a...
Read more >
Reactnativereanimated Usesharedvalue Does Not Update In ...
Companies that turn to collective impact will not only advance social progress but also find ... useAnimatedStyle does not rerender when sharedValue changes...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found