reactjs - 如何为 React Navigation 的 Tab.Screen 构建可重用组件?
问题描述
学习 React Navigation 6 我正在使用旧的 Tab Navigator 并对其进行升级,重点是 DRY 原则:
旧标签导航器:
<Tab.Navigator screenOptions={tabOptions}>
<Tab.Screen
name={routes.HOME}
component={HomeScreen}
options={{
tabBarIcon: ({ focused }) => (
<View
style={{
position: 'absolute',
top: 20,
}}
>
<FontAwesome5
name="home"
size={20}
color={focused ? colors.red : colors.grey}
></FontAwesome5>
</View>
),
}}
listeners={({ navigation, route }) => ({
tabPress: e => {
Animated.spring(tabOffsetValue, {
toValue: 0,
useNativeDriver: true,
}).start()
},
})}
/>
<Tab.Screen
name={routes.SEARCH}
component={SearchScreen}
options={{
tabBarIcon: ({ focused }) => (
<View
style={{
position: 'absolute',
top: 20,
}}
>
<FontAwesome5
name="search"
size={20}
color={focused ? colors.red : colors.grey}
></FontAwesome5>
</View>
),
}}
listeners={({ navigation, route }) => ({
tabPress: e => {
Animated.spring(tabOffsetValue, {
toValue: getWidth(),
useNativeDriver: true,
}).start()
},
})}
/>
</Tab.Navigator>
因为我在重复options
并且我没有使用 Font Awesome 以外的任何图标,所以我尝试构建一个组件:
const TabScreen = ({ name, component, icon }) => {
return (
<Tab.Screen
name={name}
component={component}
options={{
tabBarIcon: ({ focused }) => (
<View style={styles.tabBar}>
<FontAwesome5
name={icon}
size={20}
color={focused ? colors.red : colors.gray}
></FontAwesome5>
</View>
),
}}
listeners={({ navigation, route }) => ({
tabPress: e => {
Animated.spring(tabOffsetValue, {
toValue: 0,
useNativeDriver: true,
}).start()
},
})}
/>
)
}
但我在终端的错误是:
Error: A navigator can only contain 'Screen', 'Group' or 'React.Fragment' as its direct children (found 'TabScreen' for the screen 'Home'). To render this component in the navigator, pass it in the 'component' prop to 'Screen'.
所以我只为options
:
tabScreenIcon.js:
const tabScreenIcon = name => {
return {
tabBarIcon: ({ focused }) => (
<View style={styles.icon}>
<FontAwesome5 name={name} size={20} color={focused ? colors.red : colors.grey} />
</View>
),
}
}
const styles = StyleSheet.create({
icon: {
position: 'absolute',
top: 20,
},
})
应用程序.js:
<Tab.Screen
name={routes.HOME}
component={HomeScreen}
options={tabScreenIcon('home')}
listeners={({ navigation, route }) => ({
tabPress: e => {
Animated.spring(tabOffsetValue, {
toValue: 0,
useNativeDriver: true,
}).start()
},
})}
/>
<Tab.Screen
name={routes.SEARCH}
component={SearchScreen}
options={tabScreenIcon('search')}
listeners={({ navigation, route }) => ({
tabPress: e => {
Animated.spring(tabOffsetValue, {
toValue: getWidth(),
useNativeDriver: true,
}).start()
},
})}
/>
现在我正在尝试让我的动画工作,而我的选项卡屏幕仍然不是 DRY 有没有办法构建一个Tab.Screen
我可以通过 propsname
和component
动画值的可重复使用的动画?
解决方案
导航器具有适用于所有屏幕的screenListeners
和道具。screenOptions
你不需要重复它们。
https://reactnavigation.org/docs/screen-options#screenoptions-prop-on-the-navigator https://reactnavigation.org/docs/navigation-events/#screenlisteners-prop-on-the-navigator
推荐阅读
- php - 带有额外分组的mysql排序字段增量值
- swift - 为什么我不能将某些表达式传递给标记为 @convetion(block) 的闭包参数?
- hyperledger-fabric - 在超级账本资源管理器中创建多个对等点的问题
- eclipse - 如何读取使用 EMF 和 XText 创建的 DSL 实例模型文件?
- react-native - TypeError:Font.isLoaded 不是函数,(在 'Font.isLoaded(fontName)' 中,'Font.isLoaded' 未定义)在 Expo
- python-3.x - 如何打印具有多个值的字典键
- nlp - 对具有整体积极情绪但有消极词的句子进行情绪分析
- java - 就像在笔记应用程序中一样,如何实现仅由手写笔或手指接受输入的edittext?
- android - 启动 Delphi Android 应用程序时“找不到类 TForm1”。应用程序运行良好
- r - 如何在时间序列数据中创建变量,计算每个唯一年份值的另一个变量中 1 的数量