1,自定义路由
家喻户晓,不论是在原生 Android 还是 iOS,它们都有一个默认的路由路由栈治理类。因为 React Native 官网没有提供路由治理的组件,所以咱们须要应用 react-navigation 插件提供的 Stack.Navigator 组件来治理路由。
Stack.Navigator 应用的命名路由,所谓命名路由,指的是路由须要先申明而后能力应用。为了方便管理路由页面,咱们会将路由放到一个对立的地位,比方 screens 包下,如下所示。
而后,咱们在我的项目的 screens/index.js 文件中新建一个常量,次要用来治理申明的路由,如下所示。
export const stacks = [
{
name: 'AllMovieScreen',
component: AllMovieScreen,
options: {headerShown: false},
},
{
name: 'CitySelectScreen',
component: CitySelectScreen,
options: {title: '抉择城市'},
},
…. // 省略其余路由页面
];
而后,咱们再新建一个 MainStackScreen.js 文件,用来实现路由的跳转、返回等操作。同时,MainStackScreen 类的另一个作用是对立导航栏的款式,代码如下所示。
onst MainStack = createStackNavigator();
function MainStackScreen({navigation}) {
return (
<MainStack.Navigator
initialRouteName="App"
screenOptions={{
headerTitleAlign: 'center',
headerStyle: {shadowOffset: {width: 0, height: 0},
shadowColor: '#E5E5E5',
backgroundColor: '#fff',
},
gestureEnabled: true,
headerBackTitleVisible: false,
headerLeft: () => (
<TouchableOpacity
onPress={() => navigation.goBack()}
style={{padding: 10, paddingRight: 30}}>
<Icon name="chevron-thin-left" size={20} color="#222222" />
</TouchableOpacity>),
}}>
<MainStack.Screen
name="App"
component={BottomTab}
options={{headerShown: false}}/>
{stacks.map((item, index) => (
<MainStack.Screen
key={index.toString()}
name={item.name}
component={item.component}
options={item.options}/>
))}
</MainStack.Navigator>
);
}
export default MainStackScreen;
在下面的代码,咱们创立了一个 creens/index.js 文件来申明利用的路由,而后在 MainStackScreen 类中应用 map 循环实现路由的注册。能够看到,通过下面的解决后,路由治理是十分清晰的,当有新的页面时只须要往 creens/index.js 文件中增加路由即可。
2,Tab 导航
在 React Native 利用开发中,react-navigation 除了提供路由治理性能外,还反对 Tab 导航和 Drawer 导航。并且,在最新的版本中,Tab 导航、Drawer 导航和 Stack 导航所依赖的库是离开的,所以在开发过程中须要独自装置。
对于 Tab 导航来说,须要在我的项目中装置 Tab 导航须要的 bottom-tabs 库,命令如下。
npm install @react-navigation/bottom-tabs
创立 Tab 导航时须要用到 createBottomTabNavigator() 办法,它须要提供导航器和路由两个属性,别离对应 Tab.Navigator 和 Tab.Screen 两个组件,最初还须要应用 NavigationContainer 组件包裹它们,如下所示。
import {createBottomTabNavigator} from '@react-navigation/bottom-tabs';
import {NavigationContainer} from '@react-navigation/native';
const BottomTabs = createBottomTabNavigator();
export default function BottomTabScreen() {
return (
<NavigationContainer>
<BottomTabs.Navigator
initialRouteName="Home"
screenOptions={({route}) => ({tabBarIcon: ({focused}) => {
return (<Image source={ focused? tabImage[`${route.name}_active`]
: tabImage[route.name]
}
style={{width: 26, height: 26}}/>
); }})}
tabBarOptions={{
activeTintColor: 'tomato',
inactiveTintColor: 'gray',
style: {backgroundColor: '#fff',},
}}>
<BottomTabs.Screen
name="Home"
component={HomeScreen}
options={{tabBarLabel: '电影',}}/>
…. // 省略其余代码
<BottomTabs.Screen
name="Mine"
component={MineScreen}
options={{tabBarLabel: '我的',}}/>
</BottomTabs.Navigator>
</NavigationContainer>
);
}
同时,bottom-tabs 插件还提供了很多其余有用的组件和属性,开发者能够依据须要进行抉择。运行下面的代码,成果下图所示。
3,数据回传
有时候,咱们有这样一种需要:跳转到下一个页面,并在下一个页面抉择了数据后进行回传。比方:
在下面的场景中,咱们须要对流动列表进行筛选,那么在跳转到流动筛选页面后,须要回传选中的流动类型,对于这种场景,咱们须要对 react-navigation 进行怎么的解决呢?
首先,咱们在 screens/index.js 文件中注册流动类型页面,如下所示。
{
name: 'SelectorScreen',
component: SelectorScreen,
options: nav => {const {route} = nav;
const {params = {}} = route;
const {title = '流动类型', onRightPress = () => {}} = params;
return {
title,
headerRight: () => (
<TouchableOpacity
onPress={onRightPress}
style={styles.button}>
<Text style={{color: '#fff', fontSize: 14}}> 确定 </Text>
</TouchableOpacity>
),
};
},
}
同时,流动筛选页面的数据是由流动列表页面传递过去的。所以在应用的时候,只须要应用上文封装好的路由工具执行跳转操作即可,代码如下。
navigate('SelectorScreen', {values: categories.map(c => c.andGroupName),
defaultValues: categoryName,
onConfirm: changeCategory,
});
能够看到,为了获取筛选页面抉择的数据,咱们在跳转的时候定义了一个 onConfirm 回调函数。接着,咱们在新建的流动筛选页面接管上一个页面传递过去的流动数据并应用列表展现进去即可,如下所示。
function SelectorScreen({navigation, route}) {const {values = [], defaultValues = [], onConfirm} =route.params || {};
const [selected, setSelected] = useState(defaultValues);
const _onRightPress = () => {onConfirm(selected);
navigation.goBack();};
useEffect(() => {navigation.setParams({onRightPress: _onRightPress});
}, [selected]);
const onPressItem = val => {let arr = [];
arr = [val];
setSelected(arr);
};
const renderItem = ({item}) => {const renderRight = () => {const isSelected = selected.includes(item);
return (
<ListItem
text={item}
renderRight={renderRight}
onPress={() => onPressItem(item)} />
);
};
return (<View style={styles.bg}>
<FlatList
keyExtractor={(item, index) => item + index}
data={values}
renderItem={renderItem}
ListFooterComponent={<View height={120} />} />
</View>
);
};
const styles = StyleSheet.create({…. // 省略款式代码});
export default SelectorScreen;
抉择完流动类型之后,如何将抉择的后果返回给上一个页面呢。此时就用到了前文定义的 onConfirm 回调函数,如下所示。
const {values = [], defaultValues = [], onConfirm} =route.params || {};
const _onRightPress = () => {onConfirm(selected); //onConfirm 回调函数回传数据
navigation.goBack();};