美文网首页React Native开发React Native开发技巧
跟我一起学React Native之项目结构

跟我一起学React Native之项目结构

作者: Mr_Zander | 来源:发表于2018-06-12 20:57 被阅读178次

    写在前面

    这篇文章是“跟我一起学react-native”系列文章的第二篇。这系列文章会随着这个新闻项目的进行更新。想要跟我一起学习React Native的朋友可以关注我的微信公众号iOS进阶指南,或者订阅我的个人博客

    上一篇文章讲了React Native的环境搭建过程,本篇文章将讨论“水滴新闻”项目结构的搭建。

    最终效果

    效果

    项目文件结构

    rn_shuidi
     | - - - - - - - App.js
     | - - - - - - - app.json
     | - - - - - - - index.js
     | - - - - - - - node_modules
     | - - - - - - - shuidi
      | - - - - - - - home
       | - - - - - - - HomeScreen.js
       | - - - - - - - NodeScreen.js
      | - - - - - - - attention
      | - - - - - - - me
     | - - - - - - - android
     | - - - - - - - ios
     | - - - - - - - img
      | - - - - - - - home_normal.png
      | - - - - - - - home_selected.png
     | - - - - - - - package.json
    

    react-navigation

    因为项目中包含多个页面,页面之间切换要使用TabBar和Navigation,因此要使用react-navigation这个框架。
    安装react-navigation

    cd rn_shuidi
    npm install react-navigation
    

    Navigation

    下面以“主页为例”创建navigation

    App.js
    
    import { createStackNavigator, createBottomTabNavigator } from 'react-navigation'
    import HomeScreen from './shuidi/home/HomeScreen'
    import NodeScreen from './shuidi/home/NodeScreen'
    
    const HomeStack = createStackNavigator({
        Home: { screen: HomeScreen },
        Nodes: { screen: NodeScreen }
    })
    

    StackNavigation可类比为iOS中的UINavigation,是一种栈类型的导航结构。
    Home和Nodes分别是导航中的两个页面(控制器)。这里的名字会在执行导航行为的时候使用到。
    screen参数是要放在导航中的页面。

    HomeScreen.js
    
    constructor(props) {
        super(props)
        this.state = { text: 'old' }
    }
    
    static navigationOptions = {
        title: '主页',
    };
    
    <Text>{this.state.text}</Text>
    
    <Button
        title="Go to NodeScreen"
        onPress={() => {
                this.props.navigation.navigate('Nodes', {
                title: '测试节点', callback: ((data) => {
                this.setState({ text: data })
              })
           })
        }}
    />
    
    

    navigationOptions是对导航的配置,这里设置了title。相当于self.title="主页"

    点击“Go to NodeScreen”这个Button后会跳转到标签为“Nodes”的页面,如果App.js的HomeStack中不包含“Nodes”标签则不会跳转。

    title和callback分别是传递到“Nodes”页面的参数。其中callback是一个回调,用来进行反向传值。当“Nodes”页面以“data”为参数回调callback之后,this.setState保存接受到的参数,当前页面就会随之改变。

    NodeScreen.js
    
    static navigationOptions = ({ navigation }) => {
        return {
            title: navigation.getParam('title', '节点'),
        };
    };
    
    const callback = navigation.getParam('callback')
    
    <Button
        title="反向传值测试"
        onPress={() => {
            this.props.navigation.goBack(),
            callback('我是反向传值')
        }}
    />
    

    navigation.getParam('title', '节点')获取navigation中的title参数。

    点击“反向传值测试”,回到上一级页面,之后调用callback,把字符串“我是反向传值”传递到上一级页面。

    TabBar

    App.js
    
    createBottomTabNavigator(
        {
            Home: HomeStack,
            Attention: AttentionStack,
            Me: MeStack
        },
        {
            navigationOptions: ({ navigation }) => ({
                tabBarLabel: ({focused, tintColor}) => {
                    const { routeName } = navigation.state
                    var title = ''
                    if (routeName === 'Home') {
                        title = '主页'
                    } else if (routeName === 'Attention') {
                        title = '关注'
                    } else {
                        title = '我'
                    }
                    return <Text>{title}</Text>
                },
                tabBarIcon: ({ focused, tintColor }) => {
                    const { routeName } = navigation.state;
                    var iconName = '';
                    if (routeName === 'Home') {
                        iconName = focused ? require('./img/home_selected.png') : require('./img/home_normal.png')
                    } else if (routeName === 'Attention') {
                        iconName = focused ? require('./img/attention_selected.png') : require('./img/attention_normal.png')
                    } else {
                        iconName = focused ? require('./img/me_selected.png') : require('./img/me_normal.png')
                    }
                    return <Image 
                                source={iconName}
                                style={{ width: 26, height: 26 }}
                           />
                }
            }),
            tabBarOptions: {
                activeTintColor: 'blue',
                inactiveTintColor: 'black',
            }
        }
    )
    

    tabBarLabeltabBarIcon分别是当前标签页显示的标题和图片,其中图片根据focused展示不同内容。

    在navigationbar的子页面中隐藏tabbar

    HomeStack.navigationOptions = ({ navigation }) => {
        let tabBarVisible = true;
        if (navigation.state.index > 0) {
            tabBarVisible = false;
        }
    
        return {
            tabBarVisible,
        };
    };
    

    至此,项目结构搭建完成了。这个过程中如遇到问题可以参考遇到的问题和解决方案🎉🎉🎉

    如果这篇文章能为你提供些许的帮助,我将不胜荣幸。如果你能慷慨的点个赞或者关注我,我将万分感激。

    相关文章

      网友评论

      • 既然可以颠覆何必循规蹈矩:我想问问的到底是stack包裹tab好还是tab包裹stack好?
        Mr_Zander:@既然可以颠覆何必循规蹈矩 具体不清楚怎么实现的
        既然可以颠覆何必循规蹈矩:@Mr_Zander 请问你知道怎么实现微博的那张➕吗?
        Mr_Zander:@既然可以颠覆何必循规蹈矩 在iOS里面是tab包裹stack的 因为我是做iOS开发的 所以采用了这种方式。
      • Mr_panmin:谢谢楼主分享,我使用createXxx这版本的react-navigation遇到个问题,比如从底部主页点到关注,运行在Android是点击物理按键back会又跳到主页
        Mr_Zander:这个creat是我在GitHub提issue的时候 开发者告诉我的。如果安卓有问题,你可以尝试提issue或者等我过段时间在安卓上适配的时候 再来回答这个问题。不好意思

      本文标题:跟我一起学React Native之项目结构

      本文链接:https://www.haomeiwen.com/subject/dlireftx.html