通过学习RN技术,平常自己的一些笔记整理,希望借鉴

一、RN搭建开发环境
    1.安装依赖软件:
        Node.js      8.3以上      
            D:\Program Files\nodejs\

        Python       2.x以上     
            D:\Python27\         
            D:\Python27\Scripts
        JDK          1.8          
            Java_Home=C:\Program Files\Java\jdk1.8.0_65       
            %Java_Home%\bin
        Android SDK              
            ANDROID_HOME=D:\AndroidStudio\SDK
            %ANDROID_HOME%\platform-tools
            %ANDROID_HOME%\tools

    2.Yarn、React Native的命令行工具

        Yarn与npm都是软件管理工具,Yarn速度快很多

        npm(该命令是node.js中的命令,用于安装软件)

        设置npm镜像:
            npm config set registry https://registry.npm.taobao.org --global 
            npm config set disturl https://npm.taobao.org/dist --global

        Yarn、React Native的命令行工具(react-native-cli)
            npm install -g yarn react-native-cli

        安装完yarn后同理也要设置镜像源:
            yarn config set registry https://registry.npm.taobao.org --global 
            yarn config set disturl https://npm.taobao.org/dist --global4

        测试:
            react-native --version    
            yarn -v

    3.环境使用
            React开发环境:VScode
                Node.js      8.3以上 

            Android环境(编译运行环境):AS
                SDK platform:开发版本库
                    Android SDK Platform 26    (0.56)    
                    Android SDK Platform 23    (0.55.4)

                    Google Api Intel x86 Atom_64 System Image   ;   intel HAXM   (创建虚拟机使用)

                SDK bulid tools:代码编译工具
                    26.0.3                     (0.56) 
                    23.0.1                     (0.55.4)


    4.创建项目运行到模拟器:
        方式一:
            1.创建项目
                react-native init HelloWorld
                react-native init HelloWorld --version 0.55.4  
            2.进入到项目目录中
                cd HelloWorld     目录cmd
            3.运行
                react-native run-android

        方式二:
            1.导入新项目
                使用其他可用项目即可
            2.进入到项目目录中
                cd HelloWorld     目录cmd
            3.运行
                react-native run-android

        方式三:
            Android Studio打开android项目,编译运行,到模拟器
                模拟器配置设置:
                    摇一摇:启动设置页面      Ctrl+M
                    HOST:配置服务连接地址:   11.11.11.11:8081

            开启node服务:
                npm start开启

        方式四:
            直接使用.apk文件转入模拟器
                模拟器配置设置:
                        摇一摇:启动设置页面      Ctrl+M
                        HOST:配置服务连接地址:   11.11.11.11:8081
            开启node服务:
                    npm start开启

            
    5.RN常用命令:
        react-natice init HelloWorld
        react-native init HelloWorld --version 0.55.4  
        react-native --version
        react-native run-android
        react-narive run-ios   

        npm install -g yarn react-native-cli    安装软件
        npm start                               开启Node服务


二、RN项目结构:
    android      编译运行代码

    ios          编译运行代码

    node_modules  自动生成三方依赖库

    App.js     显示的组件页面

    index.js  渲染显示页面

        AppRegistry.registerComponent('HelloWorld', () => App);
            将APP组件渲染到Android获取IOS中"HelloWorld"标记

        Android渲染路径:
            @Override
            protected String getJSMainModuleName() {
                return "index";
            }

            @Override
            protected String getMainComponentName() {
                return "HelloWorld";
            }

        IOS渲染路径:
            jsCodeLocation = [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index" fallbackResource:nil];

            RCTRootView *rootView = [[RCTRootView alloc] initWithBundleURL:jsCodeLocation
                                                        moduleName:@"HelloWorld"
                                                        initialProperties:nil
                                                        launchOptions:launchOptions];
    package.json   系统项目配置文件


三、页面组件分析
    index.js  渲染显示页面
        导入依赖:react-native
        import { AppRegistry } from 'react-native';
        import App from './App';


        渲染:将App组件替换HelloWorld标记
        AppRegistry.registerComponent('HelloWorld', () => App);

    App.js    显示的组件页面

        导入依赖:react(自定义组件类)   react-native(使用RN中的控件和API)  
        import React, { Component } from "react";
        import { StyleSheet, Text, View } from "react-native";


        定义组件
        class App extends Component {

            render() {
                return (

                //渲染页面:RN中控件使用
               
                    Welcome to React Native!
                    To get started, edit App.js
                    欢迎来到LOL
               

                );
            }
        }

        //创建样式使用
        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
            }
        });


        //导出组件
         export default App;

四、基本控件以及布局样式
View
    View是一个支持Flexbox布局、样式、一些触摸处理、和一些无障碍功能的容器,
    并且它可以放到其它的视图里,也可以有任意多个任意类型的子视图

     
         
         
   

Text
    显示文本的React组件,并且它也支持嵌套、样式,以及触摸处理

    {this.state.titleText}

Image:
    不同类型图片的React组件,包括网络图片、本地资源

      同级
      下级
      上级
     同级文件夹

   

TextInput
    输入文本的基础组件。
    onChangeText的属性,此属性接受一个函数,而此函数会在文本变化时被调用。
    onSubmitEditing的属性,会在文本被提交后(用户按下软键盘上的提交键)调用

            style={{height: 40}} 
        placeholder="Type here to translate!" 
        onChangeText={(text) => this.setState({text})} />
        style={{padding: 10, fontSize: 42}}> 
        {this.state.text}
   

Button:
    显示一个简单的按钮
    是一个简单的跨平台的按钮组件。

            onPress={() => {
            Alert.alert("你点击了按钮!");
        }}
        title="点我!"
        color="#841584"
    />

Touchable系列组件:
    TouchableHighlight来制作按钮或者链接。注意此组件的背景会在用户手指按下时变暗。

    在Android 上还可以使用TouchableNativeFeedback,它会在用户手指按下时形成类似墨水涟漪的视觉效果。

    TouchableOpacity会在用户手指按下时降低按钮的透明度,而不会改变背景的颜色。

    如果你想在处理点击事件的同时不显示任何视觉反馈,则需要使用TouchableWithoutFeedback。

            onPress={this._onPressButton} //点击响应
        onLongPress={this._onLongPressButton} //长按响应
        underlayColor="white"
    >
       
            TouchableHighlight
       

     

//--------------------------------------------------------------------------------------------------    
样式:
    style的属性;驼峰命名法,例如将background-color改为backgroundColor

    还可以传入一个数组——在数组中位置居后的样式对象比居前的优先级更高,间接实现样式的继承

    使用StyleSheet.create来集中定义组件的样式

   
        just red 
        just bigblue 
        bigblue, then red 
        red, then bigblue
   

    const styles = StyleSheet.create({ 
        bigblue: { color: 'blue', fontWeight: 'bold', fontSize: 30, }, 
        red: { color: 'red', },
    });

    关于样式
    (1)普通内联样式:{{}},第一层{}是表达式,第二层{}是js对象;
                      
    (2)调用样式表:{样式类.属性}
                      
    (3)样式表和内联样式共存:{[]}
                      
    (4)多个样式表:{[样式类1, 样式类2]}
                      


弹性布局Flexbox
    Flex布局主要思想是:让容器有能力让其子项目能够改变其宽度、高度(甚至是顺序),以最佳方式填充可用空间

    容器默认存在两根轴:水平的主轴(main axis)和垂直的交叉轴;默认值是竖直轴(column)方向

    在React Native中,有4个容器属性,2个项目属性,分别是:
        容器属性:flexDirection   flexWrap   justifyContent  alignItems
        项目属性:flex  alignSelf

    flexDirection容器属性: `row | row-reverse | column | column-reverse`
        该属性决定主轴的方向(即项目的排列方向)。
        row:主轴为水平方向,起点在左端。
        row-reverse:主轴为水平方向,起点在右端。
        column(默认值):主轴为垂直方向,起点在上沿。
        column-reverse:主轴为垂直方向,起点在下沿。

    flexWrap容器属性: `nowrap | wrap | wrap-reverse`
        默认情况下,项目都排在一条线(又称"轴线")上。flex-wrap属性定义,如果一条轴线排不下,如何换行。
        nowrap(默认值):不换行
        wrap:换行,第一行在上方
        wrap-reverse:换行,第一行在下方。(和wrap相反)

    justifyContent容器属性:`flex-start | flex-end | center | space-between | space-around`
        定义了伸缩项目在主轴线的对齐方式
        flex-start(默认值):伸缩项目向一行的起始位置靠齐。
        flex-end:伸缩项目向一行的结束位置靠齐。
        center:伸缩项目向一行的中间位置靠齐。
        space-between:两端对齐,项目之间的间隔都相等。
        space-around:伸缩项目会平均地分布在行里,两端保留一半的空间。

    alignItems容器属性:`flex-start | flex-end | center | baseline | stretch`
        定义项目在交叉轴上如何对齐,可以把其想像成侧轴(垂直于主轴)的“对齐方式”。
        flex-start:交叉轴的起点对齐。
        flex-end:交叉轴的终点对齐 。
        center:交叉轴的中点对齐。
        baseline:项目的第一行文字的基线对齐。
        stretch(默认值):如果项目未设置高度或设为auto,将占满整个容器的高度。

    flex项目属性:
    “flex-grow”、“flex-shrink”和“flex-basis”三个属性的缩写,
     其中第二个和第三个参数(flex-shrink、flex-basis)是可选参数。默认值为“0 1 auto”。
     自身相对于父容器的权重占比

    alignSelf项目属性:
    “auto | flex-start | flex-end | center | baseline | stretch”
    align-self属性交叉轴允许单个项目有与其他项目不一样的对齐方式,可覆盖align-items属性。
    默认值为auto,表示继承父元素的align-items属性,如果没有父元素,则等同于stretch。


五、高级使用
ScrollView
    可滚动的容器,可放入多个组件和视图,组件并不需要是同类型的。
    ScrollView不仅可以垂直滚动,还能水平滚动(通过horizontal属性来设置)

    ScrollView必须有一个确定的高度才能正常工作,
    实际上所做的就是将一系列不确定高度的子组件装进一个确定高度的容器(通过滚动操作)

    ScrollView和ListView/FlatList区别:
        ScrollView会简单粗暴地把所有子元素一次性全部渲染出来。
        ListView会惰性渲染子元素,只在它们将要出现在屏幕中时开始渲染。
        FlatList是0.43版本开始新出的改进版的ListView,性能更优

     
        Scroll me plz 
         
         
         
         
       
   


长列表:FlatList或是SectionList
    FlatList组件用于显示一个垂直的滚动列表,其中的元素之间结构近似而仅数据不同。

    FlatList更适于长列表数据,且元素个数可以增删。
    和ScrollView不同的是,FlatList并不立即渲染所有元素,而是优先渲染屏幕上可见的元素。

    FlatList组件必须的两个属性是data和renderItem。
    data是列表的数据源,而renderItem则从数据源中逐个解析数据,然后返回一个设定好格式的组件来渲染。


    列表:
            //数据源
        data={[ {key: 'Devin'}, {key: 'Jackson'}, {key: 'James'},
         {key: 'Joel'}, {key: 'John'}, {key: 'Jillian'}, {key: 'Jimmy'}, {key: 'Julie'}, ]} 

        //Item显示组件
        renderItem={({item}) => {item.key}
    />

    分组列表
            sections={[ {title: 'D', data: ['Devin']},
         {title: 'J', data: ['Jackson', 'James', 'Jillian', 'Jimmy', 'Joel', 'John', 'Julie']}, ]} 

        renderItem={({item}) => {item}
        renderSectionHeader={({section}) => {section.title}}
    />

使用 Fetch网络请求:
    发起请求,设置参数:
        fetch("https://mywebsite.com/mydata.json0?data=1");


        //请求路径
        fetch("https://mywebsite.com/endpoint/",
        //请求设置
        {   //请求方法
            method: "POST",
            //设置请求头   
            headers: {
                Accept: "application/json",
                "Content-Type": "application/json"
            },
            //设置请求体,post;get没有body
            body: JSON.stringify({
                firstParam: "yourValue",
                secondParam: "yourOtherValue"
            })
        });

    获取响应,解析数据:
        //请求的网络路径
        fetch("https://facebook.github.io/react-native/movies.json")
        //通过箭头函数,数据解析,返回解析后的json对象
        .then(response => response.json())
        //接收解析后的json对象,获取有用数据,在状态机中做数据刷新
        .then(responseJson => {
            responseJson.movies;
        })
        //请求错误情况下进行调用
        .catch(error => {
            console.error(error);
        });

    箭头函数:
        (abc)=>(    )   :   返回 
        简写:
        abc  =>  


        (abc)=>{    }   :  函数体执行一个,无返回值


    实例:
        constructor(props) {
            super(props);

            this.state = {
                dataValue: []
            };
        }

        componentDidMount() {
            fetch("https://facebook.github.io/react-native/movies.json")
            .then(response => response.json())
            .then(responseJson => {
                //刷新数据
                this.setState({
                dataValue: responseJson.movies
                });
            })
            .catch(error => {
                console.log(error);
            });
        }


        render() {
            return (
           
                                    data={this.state.dataValue}
                    renderItem={({ item }) => (
                        {item.title}
                    )}
                />
           

            );
        }

1.请求时,出现异常

将header里面的Content-Type 设置为’application/x-www-form-urlencoded’,如果还是报错问server 端参数是什么格式 ,然后设置Content-Type的值即可.

2.响应时,出现异常

上述封装容易出现的问题在 response.json() 这一句中,如果response==null就会抛出异常,建议先判断response是否为null,如果为null 再进行特殊处理。

3.fetch设置超时的时间

fetch 本身目前没有设置超时时间的属性,只能机制来进行设置。fetch函数在各个平台的实现,如果你看到源代码的话肯定会觉得能设置超时而且很容易,但是它封装的时候并没有把 这个作为一个属性来设置.因此只能结合promise 机制使用setTimeout 来设置超时的时间。

4.https,如果server 端是无效证书 来进行https 请求的时候出现的错误

SSLHandshake: Received fatal alert: certificate_expired 
或者是 
SSLHandshake: Remote host closed connection during handshake 
六、集成原生项目
集成到现有原生应用
    1.创建RN项目
    2.AS中创建原生Android项目
    3.将RN中自带的RNActivity,RNApplication页面,导入到Android原生项目中:
        1)导入RN依赖
            在你的app中 build.gradle 文件中添加 React Native 依赖:
            dependencies { 
                ... 
                implementation "com.facebook.react:react-native:+" // From node_modules.
            }

            在项目的 build.gradle 文件中为 React Native 添加一个 maven 依赖的入口,必须写在 "allprojects" 代码块中:
            allprojects { 
                repositories { 
                    ... 
                    maven {
                    // All of React Native (JS, Android binaries) is installed from npm 
                        url "$rootDir/../node_modules/react-native/android" 
                    } 
                } 
            ... 
            }
        2)在 AndroidManifest.xml 清单文件中声明网络权限:
           
           
            DevSettingsActivity 界面(即开发者菜单),则还需要在 AndroidManifest.xml 中声明:
           

        3)在AndroidManifest.xml中声明RNActivity,RNApplication
                            android:name=".RNApplication"
                android:allowBackup="true"
                android:icon="@mipmap/ic_launcher"
                android:label="@string/app_name"
                android:roundIcon="@mipmap/ic_launcher_round"
                android:supportsRtl="true"
                android:theme="@style/AppTheme">

               
                   
                       

                       
                   
               

               
               
                   

        4)通过android项目点击事件,启动RN视图
            Intent intent = new Intent(MainActivity.this, RNActivity.class);
            startActivity(intent);

    4)将android原生项目,导入到RN/android目录:最编译运行
    5)运行app项目,启动RN服务即可


七、路由导航:
路由分类:
    StackNavigator    跳转页面,传值
    TabNavigator        左右切换导航栏
    createBottomTabNavigator   底部导航栏(图标)
    createSwitchNavigator   身份验证选择

首先是在你的应用中安装此库:
    yarn add react-navigation


1)StackNavigator路由表:
配置路由表:
    import { StackNavigator } from "react-navigation";
    import Page1 from "./Page1";
    import Details1 from "./Details1";

    const RouteABC = StackNavigator(
        {
            P: { screen: Page1 },
            D: { screen: Details1 }
        },
        {
            initialRouteName: "P"
        }
    );


跳转页面,传值取值:

    //跳转到D对应的页面,传递name,age参数
    this.props.navigation.navigate("D", { name: "张三", age: "123" });

    //在D页面中取值
     {this.props.navigation.getParam("name", "AAA")}


配置标题:
    //直接设置标题
    static navigationOptions = { title: "Page1" };
    static navigationOptions = { header: null };

    //获取传递的参数,修改为标题文本
    static navigationOptions = ({ navigation }) => ({
        title: navigation.getParam("name", "Abc")
    });

    //更改标题样式
    static navigationOptions = ({ navigation }) => ({
        title: navigation.getParam("name", "Abc"),
        headerStyle: {
            backgroundColor: "#f4511e"
        },
        headerTintColor: "#fff",
        headerTitleStyle: {
            fontWeight: "bold"
        }
    });

    //跨页面共享通用的navigationOptions
    const AppNvg = StackNavigator(
        {
            Main: { screen: HomeScreen },
            Profile: { screen: ProfileScreen },
            My: { screen: MyScreen }
        },
        {
            initialRouteName: "Main",
            navigationOptions: {
                headerStyle: {
                    backgroundColor: "#f4511e"
                },
                headerTintColor: "#fff",
                headerTitleStyle: {
                    fontWeight: "bold"
                }
            }
        }
    );

2)Tab导航栏:(自带路由功能)
import { TabNavigator } from "react-navigation";

import JHSreeen from "./JHSreeen";
import FXSreeen from "./FXSreeen";

const TieScreen = TabNavigator(
  {
    JH: {
      screen: JHSreeen,
      navigationOptions: {
        title: "精华"
      }
    },
    FX: {
      screen: FXSreeen,
      navigationOptions: {
        title: "分享"
      }
    }
  },
  {
    //设置标题栏通配效果
    navigationOptions: {
      title: "标题"
    },
    tabBarPosition: "top", //Tab摆放位置
    //谁设置文本选中前后效果颜色
    tabBarOptions: {
      activeTintColor: "white", //激活样式
      inactiveTintColor: "gray" //未激活样式
    },
    swipeEnabled: true, //是否可以滑动
    animationEnabled: true //滑动效果
  }
);


3)底部导航栏:
使用三方图库:
/**
* 图标使用:
* yarn add react-native-vector-icons
* react-native link
*
* import Ionicons from "react-native-vector-icons/Ionicons";
*
* navigationOptions中配置
*/

import { createBottomTabNavigator } from "react-navigation";
import Ionicons from "react-native-vector-icons/Ionicons";

const Home = createBottomTabNavigator(
  {
    Topic: {
      screen: Topic,
      navigationOptions: {
        title: "帖子"
      }
    },
    Publish: {
      screen: Publish,
      navigationOptions: {
        title: "发布"
      }
    },
    My: {
      screen: My,
      navigationOptions: {
        title: "我的"
      }
    }
  },
  {
    //谁设置文本选中前后效果颜色
    tabBarOptions: {
      activeTintColor: "#FF0000", //激活文本图片样式
      inactiveTintColor: "#0000FF", //未激活文本图片样式

      activeBackgroundColor: "#2296F3", //激活背景样式
      inactiveBackgroundColor: "#ffffff" //未激活背景样式
    },
    navigationOptions: ({ navigation }) => ({
      tabBarIcon: ({ focused, tintColor }) => {
        const { routeName } = navigation.state;
        let iconName;
        if (routeName === "Topic") {
          //切换不同的图标
          //iconName = `ios-document${focused ? "" : "-outline"}`;
          //iconName = `${focused ? "ios-document" : "ios-document-outline"}`;
          iconName = "ios-document";
        } else if (routeName === "Publish") {
          iconName = "ios-create";
        } else if (routeName === "My") {
          iconName = "ios-person";
        }

        return ;
      }
    })
  }
);

4)身份验证路由:

Route.js       身份验证的路由页面,主要用于配置认证页面
import { createSwitchNavigator } from "react-navigation";
import HomeScreen from "./HomeScreen";
import SignInScreen from "./SignInScreen";
import AuthLoadingScreen from "./AuthLoadingScreen";

const Route = createSwitchNavigator({
  AuthLoading: { screen: AuthLoadingScreen },
  Home: { screen: HomeScreen },
  SignIn: { screen: SignInScreen }
});


AuthLoadingScreen.js   判断登录状态,跳转不同页面

  //判断SP文件中是否保存了userToken字段:true 登录状态   false:未登录状态(读SP文件状态)
  _bootstrapAsync = async () => {
    //获取登录状态
    const userToken = await AsyncStorage.getItem("userToken");
    //根据状态判断:跳转不同页面
    this.props.navigation.navigate(userToken ? "Home" : "SignIn");
  };


SignInScreen.js   进入登录页面,说明未登录,要求用户登录(将登录信息保存到SP文件)
            title={"登录"}
        onPress={async () => {
        //登录,设置登录数据
        await AsyncStorage.setItem("userToken", "abc");
        //跳转到主页面
        this.props.navigation.navigate("Home");
        }}
    />

HomeScreen.js    进入主页面,说明已经登录成功了,用户有可能注销登录(将SP文件中的登录信息清空)
              title={"注销"}
          onPress={async () => {
            //注销清空数据
            await AsyncStorage.clear();
            //跳转到登录页面
            this.props.navigation.navigate("SignIn");
          }}
        />


八、动画使用
constructor(props) {
    super(props);

    this.state = {
      // 1. 初始化动画值
      scale: new Animated.Value(0)
    };
}


render() {
    return (
     
                  style={{
            // 2. 将动画值绑定到style的属性:opacity透明度
            // opacity: this.state.fadeAnim,
            transform: [{ scale: this.state.scale }]
          }}
        >
          RN的动画使用
       

       

你可能感兴趣的:(RN)