React Native 插值超出最大调用堆栈大小
React Native interpolate maximum call stack size exceeded
我是 RN 的新手,很难找到 "Maximum stack call exceeded"。我知道该错误与我的代码中发生的某种无限循环有关,但我找不到它。
代码
事件屏幕:
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>
);
}
}
错误
到目前为止我所了解的内容
- 这个错误似乎与我将一个 react-native-reanimated Value 从 EventScreen 传递到 CollapsibleHeaderBar 有关
- react-native-reanimated 值本身有效,因为它用于 EventScreen(参见高度插值)
- 问题似乎也与 CollapsibleHeaderBar 上的插值有关
- 从 EventScreen 注释掉 CollapsibleHeaderBar 解决了问题
- 注释掉CollapsibleHeaderBar中插值组件的样式也解决了问题
- 代码在 CollapsibleHeaderBar 的渲染阶段后显然停止工作
- 我看过其他这种跨组件动画的例子,所以理论上应该可以
- onScroll 事件从未被触发(显然错误发生在之前)
- 每个渲染函数只调用一次,所以没有循环
感谢您的帮助。
不完全确定,但尝试替换此行
onScroll={onScroll({ y: animatedValueRef })}
使用以下代码
onScroll={() => onScroll({ y: animatedValueRef })}
在我看来,onScroll
方法在每次渲染时都会被调用,并且某种状态一直在更新。
我已经解决了这个问题。我在 CollapsibleHeaderBar 上导入的 Animated 不是来自同一个库(已恢复),而是来自 react-native。改变它修复它。
我还了解到你必须将动画值放在状态中,否则动画将无法正常工作。
我是 RN 的新手,很难找到 "Maximum stack call exceeded"。我知道该错误与我的代码中发生的某种无限循环有关,但我找不到它。
代码
事件屏幕:
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>
);
}
}
错误
到目前为止我所了解的内容
- 这个错误似乎与我将一个 react-native-reanimated Value 从 EventScreen 传递到 CollapsibleHeaderBar 有关
- react-native-reanimated 值本身有效,因为它用于 EventScreen(参见高度插值)
- 问题似乎也与 CollapsibleHeaderBar 上的插值有关
- 从 EventScreen 注释掉 CollapsibleHeaderBar 解决了问题
- 注释掉CollapsibleHeaderBar中插值组件的样式也解决了问题
- 代码在 CollapsibleHeaderBar 的渲染阶段后显然停止工作
- 我看过其他这种跨组件动画的例子,所以理论上应该可以
- onScroll 事件从未被触发(显然错误发生在之前)
- 每个渲染函数只调用一次,所以没有循环
感谢您的帮助。
不完全确定,但尝试替换此行
onScroll={onScroll({ y: animatedValueRef })}
使用以下代码
onScroll={() => onScroll({ y: animatedValueRef })}
在我看来,onScroll
方法在每次渲染时都会被调用,并且某种状态一直在更新。
我已经解决了这个问题。我在 CollapsibleHeaderBar 上导入的 Animated 不是来自同一个库(已恢复),而是来自 react-native。改变它修复它。
我还了解到你必须将动画值放在状态中,否则动画将无法正常工作。