2

I'm kinda new to RN and I'm having a hard time tracking down a "Maximum stack call exceeded". I understand that the error is related to some kind of infinite loop going on in my code but I can't find it.

Code

EventScreen:

import Animated, { interpolate, Extrapolate, Value } from "react-native-reanimated";

export default class EventScreen extends React.Component<EventScreenProps, EventScreenState> {
  render() {
    const animatedValueRef = new Value(0);
    const height = interpolate(animatedValueRef, {
      inputRange: [-MAX_HEADER_HEIGHT, 0],
      outputRange: [0, MAX_HEADER_HEIGHT],
      extrapolate: Extrapolate.CLAMP
    });

    return (
      <SafeAreaView style={style.screenContainer}>
        <CollapsibleHeaderBar backgroundImage={event?.flyer} animatedValueRef={animatedValueRef} >
          <TouchableOpacity style={style.shareButton}>
            <Icon2 name="ios-share-alt" size={24} style={style.shareButtonIcon} />
            <Text style={style.shareButtonText}>CONDIVIDI</Text>
          </TouchableOpacity>
        </CollapsibleHeaderBar>
        <Animated.ScrollView
          style={style.flexOne}
          onScroll={onScroll({ y: animatedValueRef })}
          showsVerticalScrollIndicator={false}
          scrollEventThrottle={1}>
          <View style={style.cover}>
            <Animated.View style={[style.gradient, { height }]} />
            <LinearGradient style={style.flexOne} colors={["transparent", "rgba(0, 0, 0, 0.2)", Colors.appBackgroundColorValue]} />
          </View>
          ...
        </Animated.ScrollView>
        ...
      </SafeAreaView>
    )
  }
}

CollapsibleHeaderBar:

import { interpolate, Extrapolate, color } from "react-native-reanimated";

export default class CollapsibleHeaderBar extends React.PureComponent<CollapsibleHeaderBarProps> {

  render() {
    const { backgroundImage, collapsedText, animatedValueRef } = this.props;
    const opacity = interpolate(animatedValueRef, {
      inputRange: [-50, 0, HEADER_DELTA + 60],
      outputRange: [0, 0, 1],
      extrapolate: Extrapolate.CLAMP,
    });
    const textOpacity = interpolate(animatedValueRef, {
      inputRange: [HEADER_DELTA - 30, HEADER_DELTA],
      outputRange: [0, 1],
      extrapolate: Extrapolate.CLAMP,
    });
    const backgroundColor = color(18, 18, 18, interpolate(animatedValueRef, {
      inputRange: [MIN_HEADER_HEIGHT, HEADER_DELTA - 30],
      outputRange: [0.3, 1],
      extrapolate: Extrapolate.CLAMP,
    }));
    const borderBottomColor = color(65, 65, 65, interpolate(animatedValueRef, {
      inputRange: [MIN_HEADER_HEIGHT, HEADER_DELTA - 30],
      outputRange: [0.3, 1],
      extrapolate: Extrapolate.CLAMP,
    }));
    return (
      <View>
        <Animated.View style={style.headerContainer}>
          <Image style={style.backgroundImage} source={{ uri: backgroundImage }} />
          <Animated.View style={[style.barOverlay, { opacity }]} />
        </Animated.View>
        <Animated.View style={[style.barAnimation, { backgroundColor, borderBottomColor }]}>
          <View style={style.barContainer}>
            <TouchableOpacity onPress={this._onBackPressed}>
              <Icon name="chevron-left" size={24} style={style.goBackIcon} />
            </TouchableOpacity>
            <Animated.Text style={{ opacity: textOpacity }}>{collapsedText}</Animated.Text>
          </View>
          {this.props.children}
        </Animated.View>
      </View>
    );
  }
}

Error

enter image description here

What I've understood so far

  • The error seems to be related to me passing a react-native-reanimated Value from the EventScreen to the CollapsibleHeaderBar
  • The react-native-reanimated Value by itself is working since it's used on the EventScreen (see the height interpolation)
  • The problem seems also to be related to the interpolation on the CollapsibleHeaderBar
  • Commenting out the CollapsibleHeaderBar from the EventScreen solves the problem
  • Commenting out the styles with the interpolation components in the CollapsibleHeaderBar also solves the problem
  • The code apparently stops working after the render phase of the CollapsibleHeaderBar
  • I've seen other examples of this kind of cross-components animations, so theoretically it should be possible
  • The onScroll event never gets triggered (apparently the error occurs before)
  • Each render function is called only once, so the loop is not there

Thanks for your help.

Aurasphere
  • 3,841
  • 12
  • 44
  • 71

2 Answers2

2

I've solved the problem. The Animated I was importing on the CollapsibleHeaderBar was not from the same library (reanimated) but was from react-native. Changing that fixed it.

I've also learned that you have to put the animated value inside the state, otherwise the animation won't work properly.

Aurasphere
  • 3,841
  • 12
  • 44
  • 71
1

Not completely sure, but try replacing this line

onScroll={onScroll({ y: animatedValueRef })}

with following piece of code

onScroll={() => onScroll({ y: animatedValueRef })}

What seems to me is that onScroll method is called with each render, and some kind of state is updated all the time.

radovix
  • 2,756
  • 2
  • 11
  • 28
  • Hey radovix, thanks for the help! Unfortunately, I've tried that but nothing changes. Also, it seems that the render method is invoked only once in each of the two components, so the error happens before a re-render is triggered (even before the onscroll event). – Aurasphere Apr 26 '20 at 12:53
  • Sorry to hear that. Not sure where the problem is then. – radovix Apr 26 '20 at 13:02