RN 的入门了解篇

作者: CoderHG | 来源:发表于2018-07-01 23:21 被阅读113次

一、技术准备

在即将接触一项新技术的时候,应该如何入门。第一步肯定是做一下技术准备,每一项技术总是有专门的一套语言,比如 iOSOC 或者 Swift,那么 RN 又是是什么呢?直接的说是 JSX,实际上就是 JS, 毕竟 JSX 是由 JS 进化过来的。就好比 OC 是由 C 语言 进化而来的一样。

那么对于语言基础,我们应该如何准备呢?下面我罗列了一个表:

  • 1.语言
  • 2.变量
  • 3.语句
  • 4.函数
  • 5.对象

感觉任何技术的任何语言,只要弄明白了以上的五个点,那么就可以实战了。这个期间不用太深入,毕竟很多的理解还需要到实战中去。当然了,主要还是看个人悟性的高低。

比如我在学习 变量 的时候,对应着 iOS 开发中的变量来做对比,做了如下的总结:
首先给出代码:

    <!--var 与 let-->
    <script>
        {
            let a_a = '18';
            var b_a = '220';
            // 默认是 var 声明
            c_a = '320';
        }
        // 不能访问
        console.log(a_a);
        // b_a c_a 均可访问
        console.log(b_a);
        console.log(c_a);
    </script>

    <!--全局变量访问-->
    <script>
        // 函数
        function cusFunc()
        {
            // 能访问到 b_a 与 c_a
            console.log("Hello World!" + '_' + b_a + '_' + c_a);
        }
    </script>
    <!--变量删除-->
    <script>
        {
            var a_d = 5;
            b_d = 4;
            let c_d = 7;

            console.log(a_d);
            a_d = 567;
            delete  a_d; // 无效
            // a_d 可以正常使用
            console.log(a_d);

            console.log(b_d);
            b_d = 467;
            delete  b_d; // 删除定义
            //  b_d = 679; // 这一步相当于从新定义了一个变量
            // 报错
            // console.log(b_d);

            console.log(c_d);
            c_d = 789;
            console.log(c_d);
            c_d = 898;
            delete c_d; // 无效
            // c_d 还可以正常使用
            console.log(c_d);
        }

    </script>

    <!--常量定义-->
    <script>
      // ES5
      {
          Object.defineProperty(window, "sex_5", {
              value:'快来男生',
              writable:false,
          });
          console.log(window.sex_5);
          // 只读 无效  不报错
          sex_5 = '快来女生';
          console.log(window.sex_5);
      }

      // ES6
      {
          const sex_6 = '快来女生';
          // sex_6 = '快来女生'; // 直接报错
          console.log(sex_6);
      }

    </script>
    
    <!--变量的前世今生-->
    <script>
      var e_a;
      // undefined
      console.log(e_a);

      // 数字类型
      e_a = 18;
      console.log(e_a);

      // 字符串类型
      e_a = 'Coder';
      console.log(e_a);
    </script>
    
    <!--提升效应-->
    <script>
      // 变量提升 打印 undefined ,不抛出异常
      console.log(xxxx);
      var xxxx = 999;

      // 第一次定义
      function xxxxFunc() {
          console.log('one');
      }

      // d打印的是 two, 不是 One
      xxxxFunc();
      // 第二次定义
      function xxxxFunc() {
          console.log('Two');
      }
    </script>
    <button onclick="cusFunc()">快来点我啊</button>

然后对以上的代码做总结:

1.1 var 与 let 变量

  • 1 通过 var 与 let 均可定义变量。
  • 2 var 属于全局变量,let 主要是限制其作用域,即局部变量。
  • 3 默认(比如 c)为 window 的一个属性。
  • 开发中,尽量使用 let。

1.2 变量删除

除了 window 属性,均不可删除。

1.3 常量的定义

  • 1 ES5 需要借助 Object.defineProperty 来定义常量,给常量赋新值无效,但是不报错。
  • 2 ES6 直接只用 const,给常量赋值无效,直接报错。

1.4 变量的前世今生

同一个变量,可以赋值于任何类型的值。

1.5 变量提升

    1. 可以使用后面定义的 变量,但是当前的值是 undefine。
    1. 同一个同名函数的定义,以最后一个定义的为准。

1.6 异同于 iOS(OC & Swift)

  • 1.var 与 let 仅用于 Swift 中,然而在 Swift 中的 let 代表的是一个常量定义以及可变与不可变之分,与作用域无关。同时 Swift 的变量定义必须要在定义的时候指定其类型,否则报错。
  • 2.iOS 不可以 delete 变量,但是超出作用域就无效。其作用域由定义的位置与括号决定。
  • 3.iOS 中同一个变量只能有一种类型。
以上是我在做 RN 之前对变量的总结,当然其它的小知识点也是类似。

二、创建RN新项目

终端命令:

react-native init HGDev

init

使用 WebstormHGDev 打开。

image.png

对于初学者来说,只用在乎 App.js 与 index.js 这两个文件即可。

  • index.js 类似 iOS 中的 main.m 文件。
  • App.js 类似 iOS 中的 AppDelegate.m 文件。

三、App.js 的简单介绍

完整内容如下:

/**
 * Sample React Native App
 * https://github.com/facebook/react-native
 * @flow
 */

// 组件的导入,其中包括系统组件与自定义组件的导入
import React, { Component } from 'react';
import {
  Platform,
  StyleSheet,
  Text,
  View
} from 'react-native';

// 定义了一个常量字符串, 通过 Platform 来判断在 iOS 与 Android上返回不同的值.
const instructions = Platform.select({
  ios: 'Press Cmd+R to reload,\n' +
    'Cmd+D or shake for dev menu',
  android: 'Double tap R on your keyboard to reload,\n' +
    'Shake or press menu button for dev menu',
});

// 这个 Props 暂时理解不是太清晰
type Props = {};

// 通过 class 定义一个组件, 在 RN 中出了使用 class, 还能通过函数(function)
export default class App extends Component<Props> {
  // 界面渲染方法
  render() {
    return (
      <View style={styles.container}>
        <Text style={styles.welcome}>
          Welcome to React Native!
        </Text>
        <Text style={styles.instructions}>
          To get started, edit App.js
        </Text>
        <Text style={styles.instructions}>
          {instructions}
        </Text>
      </View>
    );
  }
}

// 样式定义
const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: '#F5FCFF',
  },
  welcome: {
    fontSize: 20,
    textAlign: 'center',
    margin: 10,
  },
  instructions: {
    textAlign: 'center',
    color: '#333333',
    marginBottom: 5,
  },
});

以上的代码很简单,我也初略的添加了一点注释。总共分成4个部分:

  • 1.组件导入,包括系统组件与自定义组件,关键字: importfrom
  • 2.常量定义, 比如 const instructionstype props
  • 3.组件定义,关键字有:export default class extends
  • 4.定义样式 StyleSheet

四、一个简单的例子

现在直接在 App.js 中修改,主要使用到的组件为系统的 FlatList

Simulator Screen Shot - iPhone 6 - 2018-06-30 at 13.05.20.png

具体代码如下:

// 导入组件
import React from 'react'
import {
    View,
    Text,
    StyleSheet,
    FlatList,
    TouchableOpacity,
    Image
} from 'react-native'

// 定义组件
class HGHomeContainer extends React.Component {
    // item 的点击事件
    _itemPress (item) {
        alert(item.title);
    }

    // cell 的组件
    _rendeItem(item) {
        return (
            <TouchableOpacity
                key = {item.index}
                style = {styles.itemStyle}
                onPress = {() => {item.item.func(item.item)}}
            >
                <Image
                    source={require('../sources/home/love.png')}
                    style = {styles.itemImageStyle}
                />
                <View style = {styles.itemRightContentStyle}>
                    <Text style={{marginVertical: 5}}>{item.item.title}</Text>
                    <Text style={{marginVertical: 5}}>{item.item.des}</Text>
                </View>
                <Image
                    source = {require('../sources/home/forward.png')}
                    resizeMode={'center'}
                />

            </TouchableOpacity>
        );
    }

    // 当前组件的渲染函数
    render(){
        // 数据
        let datas = [];
        for (let i=0; i<100; i++) {
            datas.push({title:('标题' + i), key:(i + ''), des:('描述' + i), func:this._itemPress})
        }

        return (
            <View style={styles.container}>
                <FlatList
                data = {datas}
                renderItem = {this._rendeItem}
                />
            </View>
        );
    }
}

// 定义样式
const styles = StyleSheet.create({
    container: {
        flex:1,
        marginTop:30,
    },
    itemStyle:{
        flexDirection:'row',
        alignItems:'center',
        borderBottomWidth:1,
        borderBottomColor:'#E6E6E6',
        marginHorizontal: 10,
        marginVertical: 5,
        paddingBottom:10,
    },
    itemRightContentStyle:{
        justifyContent:'space-between',
        flex:1,
        marginLeft:10,
    },
    itemImageStyle: {
        backgroundColor:'yellow',
        // resizeMode:'stretch',
        width:60,
        height:60,
    }
});

// 导出组件, 作为默认
export default HGHomeContainer;

这个功能主要使用的技术点是 FlatList 组件的使用, 与 ** StyleSheet** 中的 Flex 布局。
这个功能很简单,但是对于初学者来说先弄明白了,显得很重要。其实这些在官网上都有介绍。但是,像 FlatList 在官网上的,有两个例子:一个简单得根本就学不到什么东西,然后接下来给了一个很强悍的例子,强悍的不知所云,只能是自己通过各种的上网查阅。

对于 Flex 布局也是,网上也有很多的额介绍,并且介绍得都很专业,专业得让初学者根本不知道应该如何实战,很少找到一个实际的例子。对于 Flex 布局,参考我上面的例子,再结合下面的这句话,应该理解得就差不多了。

flex:1 表示当前组件可以占满父视图所剩余的空间。 如果当前组件的兄弟组件也带有 flex 属性,那么会按照具体的数字作为比例进行显示。

以上的 所剩余 的意思是排除那些有固定尺寸的组件所占据的空间。

四、项目结构

可以花一两天的时间学习一下:React Navigation.基本上就能对项目结构的搭建有所了解,然后开工进项目吧。
对于项目的搭建,我尝试着弄了一个小 Demo。现在大致的目录结构如下:

image.png
仅供参考,仅仅合适小 Demo。

相关文章

网友评论

    本文标题:RN 的入门了解篇

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