<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          React Native自定義路由管理

          共 6187字,需瀏覽 13分鐘

           ·

          2022-06-26 11:27

          ????關(guān)注后回復(fù) “進群” ,拉你進程序員交流群????


          作者丨xiangzhihong

          來源:

          https://segmentfault.com/a/1190000040441556

          1,自定義路由

          眾所周知,不管是在原生Android還是iOS,它們都有一個默認的路由路由棧管理類。由于React Native官方?jīng)]有提供路由管理的組件,所以我們需要使用react-navigation插件提供的Stack.Navigator組件來管理路由。

          Stack.Navigator使用的命名路由,所謂命名路由,指的是路由需要先聲明然后才能使用。為了方便管理路由頁面,我們會將路由放到一個統(tǒng)一的位置,比如screens包下,如下所示。

          然后,我們在項目的screens/index.js文件中新建一個常量,主要用來管理聲明的路由,如下所示。

          export const stacks = [
          {
          name: 'AllMovieScreen',
          component: AllMovieScreen,
          options: {headerShown: false},
          },
          {
          name: 'CitySelectScreen',
          component: CitySelectScreen,
          options: {title: '選擇城市'},
          },
          …. //省略其他路由頁面
          ];

          然后,我們再新建一個MainStackScreen.js文件,用來實現(xiàn)路由的跳轉(zhuǎn)、返回等操作。同時,MainStackScreen類的另一個作用是統(tǒng)一導(dǎo)航欄的樣式,代碼如下所示。

          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;

          在上面的代碼,我們創(chuàng)建了一個creens/index.js文件來申明應(yīng)用的路由,然后在MainStackScreen 類中使用map循環(huán)完成路由的注冊。可以看到,經(jīng)過上面的處理后,路由管理是非常清晰的,當有新的頁面時只需要往creens/index.js文件中添加路由即可。

          2,Tab導(dǎo)航

          在React Native應(yīng)用開發(fā)中,react-navigation除了提供路由管理功能外,還支持Tab導(dǎo)航和Drawer導(dǎo)航。并且,在最新的版本中,Tab導(dǎo)航、Drawer導(dǎo)航和Stack導(dǎo)航所依賴的庫是分開的,所以在開發(fā)過程中需要單獨安裝。

          對于Tab導(dǎo)航來說,需要在項目中安裝Tab導(dǎo)航需要的bottom-tabs庫,命令如下。

          npm install @react-navigation/bottom-tabs

          創(chuàng)建Tab導(dǎo)航時需要用到createBottomTabNavigator()方法,它需要提供導(dǎo)航器和路由兩個屬性,分別對應(yīng)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插件還提供了很多其他有用的組件和屬性,開發(fā)者可以根據(jù)需要進行選擇。運行上面的代碼,效果下圖所示。

          3,數(shù)據(jù)回傳

          有時候,我們有這樣一種需求:跳轉(zhuǎn)到下一個頁面,并在下一個頁面選擇了數(shù)據(jù)后進行回傳。比如:

          在上面的場景中,我們需要對活動列表進行篩選,那么在跳轉(zhuǎn)到活動篩選頁面后,需要回傳選中的活動類型,對于這種場景,我們需要對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>
          ),
          };
          },
          }

          同時,活動篩選頁面的數(shù)據(jù)是由活動列表頁面?zhèn)鬟f過來的。所以在使用的時候,只需要使用上文封裝好的路由工具執(zhí)行跳轉(zhuǎn)操作即可,代碼如下。

          navigate('SelectorScreen', {
          values: categories.map(c => c.andGroupName),
          defaultValues: categoryName,
          onConfirm: changeCategory,
          });

          可以看到,為了獲取篩選頁面選擇的數(shù)據(jù),我們在跳轉(zhuǎn)的時候定義了一個onConfirm回調(diào)函數(shù)。接著,我們在新建的活動篩選頁面接收上一個頁面?zhèn)鬟f過來的活動數(shù)據(jù)并使用列表展示出來即可,如下所示。

          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;

          選擇完活動類型之后,如何將選擇的結(jié)果返回給上一個頁面呢。此時就用到了前文定義的onConfirm回調(diào)函數(shù),如下所示。


          const {values = [], defaultValues = [], onConfirm} =route.params || {};

          const _onRightPress = () => {
          onConfirm(selected); //onConfirm回調(diào)函數(shù)回傳數(shù)據(jù)
          navigation.goBack();
          };

          -End-

          最近有一些小伙伴,讓我?guī)兔φ乙恍?nbsp;面試題 資料,于是我翻遍了收藏的 5T 資料后,匯總整理出來,可以說是程序員面試必備!所有資料都整理到網(wǎng)盤了,歡迎下載!

          點擊??卡片,關(guān)注后回復(fù)【面試題】即可獲取

          在看點這里好文分享給更多人↓↓

          瀏覽 39
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  91性愛视频 | 国产成人亚洲一区二区三区 | 777国产盗拍偷窥0000 | 欧美日韩中文 | 杨思敏一级婬片A片 |