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(); };