我正在寻找以下(标准)用例的最佳实践解决方案:
我有多个带有ScrollViews或Lists的屏幕(与react-navigation
连接)。屏幕有时具有相同的标题,有时具有不同的标题。这些标题包括动画,具体取决于视图的滚动位置。在创建导航器(父视图)时,有时会安装标头,有时会在视图中对其进行修改。
所以我的问题基本上是,我该如何共享一个普通的scrollY变量
const scrollY = useRef(new Animated.Value(0)).current
与其他组件(尤其是如果它们安装在父组件中,例如Header)。另外,如果视图发生更改,如何重置此变量,或者每个屏幕都使用scrollY
自己的实例?
我想要一个带有钩子的解决方案,例如:
const ParentComponent = props => (
<MainStack.Navigator
screenOptions={{
header: props => <Header {...props}/>
}}
>
<MainStack.Screen
name="Screen1"
component={Screen1}
/>
<MainStack.Screen
name="Screen2"
component={Screen2}
/>
</MainStack.Navigator>
)
// Similar to Screen2
const Screen1 = props => {
// get the global?! scrollY
const scrollY = useScrollY();
return(
<Animated.ScrollView
onScroll={
Animated.event(
[
{
nativeEvent: {contentOffset: {y: scrollY}}
}
]
)
}
>
</Animated.ScrollView>
);
}
// Header
const Header = props => {
// get the relevant scrollY variable from Screen1 or Screen2
const scrollY = useScrollY();
const animation = scrollY.interpolate({...})
return (...);
}
我有一个可行的解决方案,将scrollY放入redux,但它似乎有问题且运行缓慢。另外,我尝试在文件范围内创建全局scrollY(请注意以下内容),并使其可以通过函数进行访问。但这不是很像React。在最高组件中创建scrollY并通过props向下传递也不是真正的选择,因为实际上层次结构已经太复杂了。我想有一个简单,高效,最佳实践的解决方案来共享scrollY,最好通过一个钩子来共享。有什么想法吗?
注意:首先尝试使用文件作用域变量
let scrollY = new Animated.Value(0);
let history = {};
export const useScrollY = () => {
const reset = useCallback(
() => {
scrollY = new Animated.Value(0);
},
[]
);
return [scrollY, reset];
};
这里的问题是,在StackNavigator方案中,尽管滚动位置可能仍然不同,但父堆栈将重置为滚动位置0的动画。我还尝试了使用历史记录变量的方法,但那实际上没有用。
答案 0 :(得分:0)
我认为您可以通过将动画值从父级传递给子级来实现。
例如:
const ParentComponent = props => {
const [scrollY] = useState(()=> new Animated.Value(0));
return <MainStack.Navigator
screenOptions={{
header: props => <Header {...props} {...{scrollY}}/>
}}
>
<MainStack.Screen
name="Screen1"
>
{(props)=> <Screen1 {...props} {...{scrollY}} />}
</MainStack.Screen>
<MainStack.Screen
name="Screen2"
component={Screen2}
/>
</MainStack.Navigator>
)