ReactNative 学习成果总结(中)

简介: ReactNative 学习成果总结(中)

3.DOM DOM 是前端的一个概念,暂时可以粗略理解为一个页面的树形结构。 React 生命周期的三大阶段

  • Mounting:已插入真实 DOM
  • Updating:正在被重新渲染
  • Unmounting:已移出真实 DOM

在每个阶段都有相应的状态和与之对应的回调函数,具体可以看下图:


image.png


上图来自:贾鹏辉的技术博客:React Native之React速学教程(中)


集成与管理


1.指定版本初始化 在终端输入react-native demo --version 0.40.0命令以后,就会初始化一个React Native版本为0.40.0的项目。这个最初项目里面直接就包含了iOS和Android的工程文件夹,可以用对应的IDE打开后编译运行。

在新建一个React Native项目之后的根目录结构是这样的:


image.png


2.使用 Cocoapods 管理 ReactNative Podfile 文件格式:

pod 'React', :path => './node_modules/react-native', :subspecs => [
  'Core',
  'RCTText',
  'RCTImage',
  'RCTActionSheet',
  'RCTGeolocation',
  'RCTNetwork',
  'RCTSettings',
  'RCTVibration',
  'RCTWebSocket',
  ]


ReactNative 0.42.0 以上版本需在 Podfile 配置 yoga:

# 如果你的RN版本 >= 0.42.0,请加入下面这行
pod "yoga", :path => "./node_modules/react-native/ReactCommon/yoga"

输入react-native run-ios或者react-native run-android指令, 就会自动打开模拟器运行项目(前提是安装了相应的开发环境)。


但是一个比较完整的项目仅仅有这些类别的文件是不够的,还需要一些工具类,模型类,资源等文件。为了很好地区分它们,使项目结构一目了然,需要组织好项目文件夹以及类的命名,下面是我将教程里的文件夹命名和结构稍加修改后的一个方案,可供大家参考:


image.png


布局约束


采用Flex布局的元素,被称为Flex container,其所有子元素被称为Flex item;容器默认存在两个轴,分别是主轴(main axis)和垂直的交叉轴(cross axis),主轴开始的位置叫做main start,结束的位置叫main end;交叉轴的开始位置叫做cross start,结束的位置叫做cross end;单个item占据的主轴空间叫做main size,占据的交叉轴控件叫做cross size。

如下图所示:


image.png


组件化驱动下,搜索结果页中展示的 Cell 与之前的列表页 Cell 可以重用:



image.png


我们把该组件定名为:RespositoryCell,结合代码来看一下具体的实现:

export default class RepositoryCell extends Component {
    constructor(props) {
        super(props);
        this.state = {
            isFavorite: this.props.projectModel.isFavorite,
            favoriteIcon: this.props.projectModel.isFavorite ? require('../../res/images/ic_star.png') : require('../../res/images/ic_unstar_transparent.png'),
        };
    }
    componentWillReceiveProps(nextProps) {
        this.setFavoriteState(nextProps.projectModel.isFavorite)
    }
    setFavoriteState(isFavorite) {
        this.props.projectModel.isFavorite = isFavorite;
        this.setState({
            isFavorite: isFavorite,
            favoriteIcon: isFavorite ? require('../../res/images/ic_star.png') : require('../../res/images/ic_unstar_transparent.png')
        })
    }
    onPressFavorite() {
        this.setFavoriteState(!this.state.isFavorite)
        this.props.onFavorite(this.props.projectModel.item, !this.state.isFavorite)
    }
    render() {
        let item = this.props.projectModel.item? this.props.projectModel.item:this.props.projectModel;
        let favoriteButton=this.props.projectModel.item?
            <TouchableOpacity
                style={{padding:6}}
                onPress={()=>this.onPressFavorite()} underlayColor='transparent'>
                <Image
                    ref='favoriteIcon'
                    style={[{width: 22, height: 22,},this.props.theme.styles.tabBarSelectedIcon]}
                    source={this.state.favoriteIcon}/>
            </TouchableOpacity>:null;
        return (
            <TouchableOpacity
                onPress={this.props.onSelect}
                style={styles.container}
            >
                <View style={styles.cell_container}>
                    <Text style={styles.title}>{item.full_name}</Text>
                    <Text style={styles.description}>{item.description}</Text>
                    <View style={styles.row}>
                        <View style={styles.row}>
                            <Text>Author:</Text>
                            <Image
                                style={{height: 22, width: 22}}
                                source={{uri: item.owner.avatar_url}}
                            />
                        </View>
                        <View style={{justifyContent: 'space-between', flexDirection: 'row'}}>
                            <Text>Star:</Text>
                            <Text>{item.stargazers_count}</Text>
                        </View>
                        {favoriteButton}
                    </View>
                </View>
            </TouchableOpacity>
        )
    }
}
  • 这里声明了RespositoryCell组件,它继承于Component,也就是组件类,即是说,声明组件的时候必须都要继承与这个类。
  • 集中看一下该组件的render方法,它返回的是该组件的实际布局:在语法上使用JSX,类似于HTML的标签式语法,很清楚地将cell的层级展现了出来:
  • 最外层被一个View组件包裹着,里面第一层有三个子组件:两个Text组件和一个作为底部背景的View组件。
  • 底部背景的View组件又有三个子组件:View组件(显示作者信息),View组件(显示star信息),收藏按钮。

结构分解图:


image.png


组件封装


image.png


对于“我的页面”和“个人中心”这类结构相似的页面,建议进行组件封装,封装后的 AboutPage 实现代码简洁如下:

export default class AboutPage extends Component{
    constructor(props) {
        super(props);
        this.aboutCommon=new AboutCommon(props,(dic)=>this.updateState(dic),FLAG_ABOUT.flag_about,config);
        this.state = {
            projectModels: [],
            author:config.author
        }
    }
    componentDidMount() {
        this.aboutCommon.componentDidMount();
    }
    componentWillUnmount() {
        this.aboutCommon.componentWillUnmount();
    }
    updateState(dic){
        this.setState(dic);
    }
    onClick(tab) {
        let TargetComponent, params = {...this.props,menuType:tab};
        switch (tab) {
            case MORE_MENU.About_Author:
                TargetComponent = AboutMePage;
                break;
            case MORE_MENU.Website:
                TargetComponent = WebViewPage;
                params.title='GitHubPopular';
                var url='https://reversescale.github.io';
                params.url=url;
                break;
            case MORE_MENU.Feedback:
                var url='mailto://reversescale@icloud.com';
                Linking.canOpenURL(url).then(supported => {
                    if (!supported) {
                        console.log('Can\'t handle url: ' + url);
                    } else {
                        return Linking.openURL(url);
                    }
                }).catch(err => console.error('An error occurred', err));
                break;
            case MORE_MENU.Share:
                break;
        }
        if (TargetComponent) {
            this.props.navigator.push({
                component: TargetComponent,
                params: params,
            });
        }
    }
    render() {
        let content=<View>
            {this.aboutCommon.renderRepository(this.state.projectModels)}
            {ViewUtils.getSettingItem(()=>this.onClick(MORE_MENU.Website), require('../../../res/images/ic_computer.png'), MORE_MENU.Website, this.props.theme.styles.tabBarSelectedIcon)}
            <View style={GlobalStyles.line}/>
            {ViewUtils.getSettingItem(()=>this.onClick(MORE_MENU.About_Author), require('../my/img/ic_insert_emoticon.png'), MORE_MENU.About_Author, this.props.theme.styles.tabBarSelectedIcon)}
            <View style={GlobalStyles.line}/>
            {ViewUtils.getSettingItem(()=>this.onClick(MORE_MENU.Feedback), require('../../../res/images/ic_feedback.png'), MORE_MENU.Feedback, this.props.theme.styles.tabBarSelectedIcon)}
        </View>
        return this.aboutCommon.render(content, {
            'name': 'GitHub Popular',
            'description': '这是一个用来查看GitHub最受欢迎与最热项目的App,它基于React Native支持Android和iOS双平台。',
            "avatar": "http://og1yl0w9z.bkt.clouddn.com/18-3-28/61685877.jpg",
            "backgroundImg": "http://og1yl0w9z.bkt.clouddn.com/18-3-28/37407402.jpg",
        });
    }
}


目录
相关文章
|
3月前
|
设计模式 Java Android开发
探索安卓应用开发:从新手到专家的旅程探索iOS开发中的SwiftUI框架
【8月更文挑战第29天】本文旨在通过一个易于理解的旅程比喻,带领读者深入探讨安卓应用开发的各个方面。我们将从基础概念入手,逐步过渡到高级技术,最后讨论如何维护和推广你的应用。无论你是编程新手还是有经验的开发者,这篇文章都将为你提供有价值的见解和实用的代码示例。让我们一起开始这段激动人心的旅程吧!
|
3月前
|
持续交付 测试技术 jenkins
JSF 邂逅持续集成,紧跟技术热点潮流,开启高效开发之旅,引发开发者强烈情感共鸣
【8月更文挑战第31天】在快速发展的软件开发领域,JavaServer Faces(JSF)这一强大的Java Web应用框架与持续集成(CI)结合,可显著提升开发效率及软件质量。持续集成通过频繁的代码集成及自动化构建测试,实现快速反馈、高质量代码、加强团队协作及简化部署流程。以Jenkins为例,配合Maven或Gradle,可轻松搭建JSF项目的CI环境,通过JUnit和Selenium编写自动化测试,确保每次构建的稳定性和正确性。
62 0
|
3月前
|
Java Android开发 开发者
探索安卓应用开发:从基础到实践
【8月更文挑战第31天】在这篇文章中,我们将一起踏上安卓应用开发的旅程。无论你是初学者还是有一定经验的开发者,这里都有适合你的内容。文章将引导你理解安卓开发的基础知识,然后通过实际的代码示例,带你一步步构建一个简单的应用程序。我们的目标是让读者能够不仅理解安卓开发的理论基础,还能通过动手实践来巩固这些知识。所以,拿起你的设备,让我们一起开始吧!
|
3月前
|
开发工具 数据安全/隐私保护 iOS开发
探索iOS应用开发的核心理念与实践
【8月更文挑战第23天】在数字时代的浪潮中,iOS应用开发不仅仅是技术的堆砌,更是一场关于创新、用户体验和持续改进的旅程。本文将深入探讨iOS应用开发的核心理念,从设计哲学到开发工具的选择,再到市场趋势的适应,旨在为开发者提供一条清晰的路径,帮助他们在不断变化的技术世界中保持竞争力和创新力。
|
4月前
|
消息中间件 缓存 NoSQL
个人项目中技术落地的基础入门(2)
个人项目中技术落地的基础入门
|
4月前
|
缓存 NoSQL Java
个人项目中技术落地的基础入门(1)
个人项目中技术落地的基础入门
107 6
|
4月前
|
存储 缓存 物联网
个人项目中技术落地的基础入门(3)
个人项目中技术落地的基础入门
|
测试技术 BI Android开发
移动app自动化测试工具发展历程--完整版
移动app自动化测试工具发展历程--完整版
209 0
移动app自动化测试工具发展历程--完整版
|
测试技术 iOS开发 Python
热饭的测开成果盘点第二十六期:IOS自动化平台
热饭的测开成果盘点第二十六期:IOS自动化平台
热饭的测开成果盘点第二十六期:IOS自动化平台
|
移动开发 JSON 前端开发
ReactNative 学习成果总结(下)
ReactNative 学习成果总结(下)
265 0
ReactNative 学习成果总结(下)