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

写在前面

这篇文章是“跟我一起学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,
    };
};

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

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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 211,348评论 6 491
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,122评论 2 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 156,936评论 0 347
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,427评论 1 283
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,467评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,785评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,931评论 3 406
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,696评论 0 266
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,141评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,483评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,625评论 1 340
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,291评论 4 329
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,892评论 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,741评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,977评论 1 265
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,324评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,492评论 2 348

推荐阅读更多精彩内容