超光速学习React Native笔记一:RN基础

FBI WARMING:必须会Ract框架,最好会ES6语法,其次是flex弹性布局和请求网络

官方文档:https://reactnative.cn/

本人萌新一天内跟着官方文档学完这基础,现在总结笔记,来带大家超光速学习,

保证一天内学完!保证一天内学完!保证一天内学完!

搭建环境

1、安装Node(版本高于8.3)

2、安装JDK(版本必须是1.8)
https://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html

3、安装Python(版本必须是2.x)

4、安装yarn和react-native手脚架(不能用cnpm,有bug)
npm install -g yarn react-native-cli

5、设置yarn的镜像源(以后安装模块就快很多)
yarn config set registry https://registry.npm.taobao.org --global
yarn config set disturl https://npm.taobao.org/dist --global

有兴趣的同学自己安装AS或各种虚拟机,我直接用真机安卓调试的(穷)。

创建项目

在你想创建项目的地方,shift+鼠标右击,选择‘在此处打开Powershell窗口’,输入:
react-native init hello,hello就是你的项目名

在安卓真机上运行项目

(不同手机系统具体操作不一样,请自行百度哦,但步骤都是几乎相似的)

1、开启开发者模式

2、开启usb调试

3、使用usb数据线连接手机和电脑

4、允许USB安装(有些手机有选项,要打开,要不然等下没有权限在手机上安装项目)

5、在项目下打开终端,输入:react-native run-android

调试

项目在手机跑起来后,摇一摇手机:

1、点击 Enable Hot Reloading,以后保存代码就会实时更新效果

2、 如果代码里写了console.log,点击 Debug JS Remotely ,电脑会自动打开浏览器,然后按 F12 打开开发者工具栏,然后你就能在控制台看到了

坑:这个刷新是有bug的,有时保存了代码,App也不会立即更新,有时需要使用react-native run-android重新编译

3、 如果你需要非常牛逼的调试方式,请打开:https://github.com/facebook/react-devtools/tree/master/packages/react-devtools ,否则你可以直接跳过看下面内容

Hello World

打开根目录的App.js,如下图所示写并运行代码

 import React, { Component } from 'react';
 import { Text, View } from 'react-native';
 
 export default class HelloWorldApp extends Component {
   render() {
     return (
         <View style={{ flex: 1, justifyContent: "center", alignItems: "center" }}>
           <Text>Hello world!</Text>
         </View>
     );
   }
 }

被export default导出的就是根组件

学习基础

导入组件:import { Text, View } from 'react-native’

坑:接下来你学到的所有组件请自觉在头部这里导入!!!

下面请在render函数的return中写代码,和react一样,只能有一个根组件,常用View组件包裹

学习建议:请把接下来学习的组件当作学习新的html标签,这样比较好受

1、View

这货就是div,用法和以前一样

注意:该组件的样式中,使用 elevation 来设置z轴高度,和z-index用法一样

2、Text

用于显示文本的组件,也支持触摸操作,像div一样占一整行,文本元素只能写在Text中,可以使用换行符

Text是文本布局,不是弹性布局,所以只支持文本样式

 <Text>Hello world!{'\n'}</Text>

3、Image 图片

这货就是img,src 变成 source

导入项目中的静态图片:require里面写你图片相对于这个组件的路径

 <Image source={require('./images/1.jpg')}/>

导入远程图片:(IOS只支持https协议的图片,而且必须设置宽高

 <Image source={uri:图片的地址} style={{width: 193, height: 30}}/>

坑1:是 uri ,不是url
坑2:Image里的require 中的路径必须是静态字符串,不能有变量,你可以如下所示拼凑路径

  var a = images
  var pic = require('./'+a+'/1.jpg')
  <Image source={pic}/>

设置背景图片,只需要用Image组件包裹内容就行,这样Image就相当于背景图:

 <Image source={require('./images/1.jpg')}>
        <Text>123</Text>	//Image就相当于以前的div中的url加载背景图的形式
 </Image>

支持的图片格式,RN默认支持JPG和PNG,ios还支持GIF、WebP,但安卓却默认不支持这两种格式

打开项目目录下的 android/gradle/build.gradle,按情况添加以下代码

 dependencies {
   compile 'com.facebook.fresco:animated-gif:0.11.0'  //需要GIF动画支持添加本行语句
   compile 'com.facebook.fresco:webpsupport:0.11.0'   //需要WebP格式支持添加本行语句
   compile 'com.facebook.fresco:animated-webp:0.11.0' //需要WebP动画支持添加本行语句
 }

resizeMode :图像显示模式,在组件内当作属性或者在样式内当作样式使用都行,如下所示

 <Image source={'./images/1.jpg'} style={{flex:1,width:200, height:100, resizeMode: Image.resizeMode.stretch}} />

有5中模式:covercontainstretchcenterrepeat

cover(默认):图片比例不变,可能不能完整展示图片,但填满Image
contain:图片比例不变,完整展示图片,但可能填不满Image
stretch :图片比例可以变化,完整展示图片,能填满Image
center :图片比例不变,完整展示图片,但可以填不满Image,图片位于显示区域的中心
repeat(iOS 独有):用一张或者多张图片来填满整个 Image区域

4、Props(属性)

组件在创建时使用的各种参数来进行设置,这些参数就称为Props

就是组件的属性都在Props中,下面是利用Props传参的例子

在import下面自定义一个叫Greeting的组件

 class Greeting extends Component {
   render(){
     return(
       <View style={{alignItems: 'center'}}>
         <Text>Hello {this.props.name}!</Text>
       </View>
     )
   }
 }

在根组件中使用

 <Greeting name='abc'/>

根组件为子组件传入了name这个自定义属性,并赋值abc,子组件通过this.props.name接收到,并在Text内展示出来

5、State(状态)

需要改变的数据就存在state中,否则就存在props中

与react用法一样,在组件内定义,与render函数同级

 state = {
     count: 0	//在这定义你需要的数据
 }

也有很多教程在构造函数中定义,但没必要这么麻烦

修改state中的数据必须使用setState()方法

 this.state.count = 100	//这样直接修改无效
 this.setState({			//这样写才对
     count : 100
 })

setState()是异步方法,你可以使用回调函数

 this.setState({count : 100}, () => { /* 你需要的操作... */ })

6、样式

注意:因为在js中写css,所以样式属性名要使用驼峰式,例如下面例子中的backgroundColor

在style中写样式,传入对象:

 <View style={{alignItems: 'center',backgroundColor: 'red'}} />

StyleSheet组件可以让我们把样式定义在外部:

一般常在在最下面定义样式

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

导入样式:

 <Text style={styles.bigBlue}>just bigBlue</Text>
 <Text style={[styles.bigBlue, styles.red]}>bigBlue, then red</Text>

多个样式用数组包裹

注意:为什么有时两个花括号,有时一个?
无论如何绑定属性只有一个花括号,两个花括号是因为在style内写样式时要传入对象

这里就稍微说一下,和react一模一样

7、宽高与布局

指定宽高,尺寸都是没有单位的,表示的是与设备像素密度无关的逻辑像素点(看不懂没关系)

 <View style={{width: 50, height: 50, backgroundColor: 'powderblue'}} />
 <View style={{width: 100, height: 100, backgroundColor: 'skyblue'}} />
 <View style={{width: 150, height: 150, backgroundColor: 'steelblue'}} />

弹性宽高,下面举个例子

 <View style={{flex: 1}}>
 	<View style={{flex: 1, backgroundColor: 'powderblue'}} />
 	<View style={{flex: 2, backgroundColor: 'skyblue'}} />
     <View style={{flex: 3, backgroundColor: 'steelblue'}} />
 </View>

RN中是默认flex布局,主轴方向是从上到下,flex的具体知识请百度

Dimensions这个API用于获取设备屏幕的宽高,常用来做安装IOS双系统界面适配

 var a = Dimensions.get('window').width;		//获取设备宽度
 var b = Dimensions.get('window').height;	//获取设备高度

8、TextInput 文本输入

这货就是input,onChange变成 onChangeText,下面是例子:

 <TextInput style={{height: 40}} placeholder="请输入" onChangeText={(text) => this.setState({text})} />

可以设置 password 属性为true来变成密码框,默认false

9、触摸组件与事件

Button:这货就是button,click变成 onPresscolor 设置按钮背景颜色

必须设置 title,这属性就是设置你的按钮上的文字

常见的触摸事件:onPress 点击、onPressIn 按下、onPressOut 抬起、onLongPress 长按

 <Button onPress={() => {alert("a")}} onLongPress={() => {alert("b")}} title="点我" color="#841584" />
 <Button>123</Button>	//这样写没用,要用title设置按钮上的文字

Button只能提供固定样式的按钮,无法设置样式

自定义按钮需要使用下面的Touchable 系列组件

该系列组件内部必须定义一个子组件,且必须只能有一个根子组件,多个子组件可以用View包裹

TouchableHighlight,按下时默认变黑

可以用 underlayColor 属性设置点击时要变化到指定颜色,activeOpacity 设置点击时的显示的不透明度(取值0-1直接)

 <TouchableHighlight onPress={() => {Alert.alert("你点击了按钮")}} underlayColor="red" style={{width: 150, height: 40, backgroundColor: 'yellow'}}>
   <View>
     <Text>Button</Text>
   </View>
 </TouchableHighlight>

坑:按钮样式最好写在按钮组件上,这是特例,下面的按钮组件,样式都写在根子组件上

TouchableOpacity,按下时变半透明,一样能使用 activeOpacity 属性

 <TouchableOpacity onPress={() => {Alert.alert("你点击了按钮")}} >
   <View style={{width: 190, height: 40, backgroundColor: 'green'}} >
     <Text>Button</Text>
   </View>
 </TouchableOpacity>

TouchableNativeFeedback ,按下时产生墨水涟漪效果

 <TouchableNativeFeedback onPress={() => {Alert.alert("你点击了按钮")}} >
   <View style={{width: 180, height: 40, backgroundColor: 'red'}}>
     <Text>Button</Text>
   </View>
 </TouchableNativeFeedback>

TouchableWithoutFeedback,无任何颜色和效果,只能设置宽高,不常用

使用场景是实现点击空白处触发某个操作,空白部分用该组件包起来,或绝对定位覆盖住

 <TouchableWithoutFeedback onPress={() => {Alert.alert("你点击了按钮")}}>
   <View style={{width: 150, height: 40, backgroundColor: 'origin'}} >
     <Text>Button</Text>
   </View>
 </TouchableWithoutFeedback>

10、ScrollView 滚动视图

ScrollView 是一个通用的可滚动的容器,可以在其中放入多个组件和视图,而且这些组件并不需要是同类型的

 <ScrollView>
   <Text style={{fontSize:150}}>Fighting</Text>
   ...
 </ScrollView>

ScrollView 必须有一个确定的高度才能正常工作
要么直接设置高度(不推荐,因为它会根据内部组件自动延伸自己的尺寸到合适的大小)
ScrollView 中不要加 flex:1

ScrollView 响应的优先级比内部组件高,没办法改变

可以设置 horizontal 属性为true,使其为横向滚动,默认为false

该组件适合显示较短或结构不一样的内容,因为所有组件都会被渲染,性能很差,较长内容用下面的长列表渲染

11、FlatList / SectionList 长列表

长列表组件会优先渲染屏幕可见区的元素,所以性能好。

FlatList适合渲染结构相似,仅仅数据不同的内容。

FlatList有两个必须设置的属性:data 是数据源,renderItem 是渲染格式

keyExtractor 属性和react列表渲染的key一样,规范来说最好设置一下,提高渲染效率

 <FlatList data={[{key: 'Devin'},{key: 'Jackson'},{key: 'James'}]}
 renderItem={({item}) => <Text>{item.key}</Text>}
 keyExtractor={(item, index) => index} />

SectionList适合渲染的是一组需要分组的数据,也许还带有分组标签

和上面相似,sections 是数据源,renderItem 是渲染格式,renderSectionHeader 是分组头部渲染格式

 <SectionList sections={[
   {title: 'D', data: ['Devin']},
   {title: 'J', data: ['Jackson', 'James', 'Jillian']},
 ]}
 renderItem={({item}) => <Text>{item}</Text>}
 renderSectionHeader={({section}) => <Text>{section.title}</Text>}
 keyExtractor={(item, index) => index} />

12、网络

Fetch

 function getMoviesFromApiAsync() {
   return fetch('https://facebook.github.io/react-native/movies.json')
     .then((response) => response.json())
     .then((responseJson) => {
       return responseJson.movies;
     })
     .catch((error) => {
       console.error(error);
     });
 }

Ajax,RN已经内置ajax,你可以直接写原生,也能用比如axios、frisbee,但不能用JQuery

而且你既可以用Promise写法,也能用Async/Await函数

WebSocket 也支持

 var ws = new WebSocket('ws://host.com/path');
 ws.onopen = () => {
   // connection opened
   ws.send('something'); // send a message
 };
 ws.onmessage = (e) => {
   // a message was received
   console.log(e.data);
 };
 ws.onerror = (e) => {
   // an error occurred
   console.log(e.message);
 };
 ws.onclose = (e) => {
   // connection closed
   console.log(e.code, e.reason);
 }; 

13、RefreshControl 下拉刷新

上面学了滚动视图和网络请求,我们就可以学下拉刷新啦

示例:

class RefreshableList extends Component {

  state = { refresh: false }

  Refresh = () => {
    this.setState({refreshing: true});
    fetchData().then(() => {
      this.setState({refreshing: false});
    });
  }
  
  render() {
    return (
      <ScrollView
        refreshControl={<RefreshControl refreshing={this.state.refresh} onRefresh={this.Refresh}/>}
        ...
      />
    );
  }
  ...
}

如上图所示,在滚动视图组件 ScrollView 中,设置 refreshControl 属性,在该属性中添加 RefreshControl 组件

refreshing 控制转圈圈的指示器是否开启,true为开启,false为关闭

onRefresh 是下拉刷新时,要执行的方法

上面例子中,该方法首先开启指示器,然后向网络请求最新数据,获取到数据后,就会关闭指示器

其它滚动组件也能使用,比如 FlatList 和 SectionList

14、生命周期函数(钩子)

超光速学习React Native笔记一:RN基础_第1张图片

上图可大致分为创建阶段,更新阶段,销毁阶段

下面我是严格按照函数的执行顺序说明的

组件加载的时候触发的函数

getDefaultProps( ):初始化默认的属性(props)
通常会将固定的内容放在这个函数中进行初始化和赋值,可以通过 this.props 获取属性,由于组件初始化后,再次使用该组件不会调用getDefaultProps函数,所以组件自己不可以自己修改props(即 props 可认为是只读的),只可由其他组件调用它时在外部修改

getInitialState( ):初始化组件状态(state)
该函数不同于getDefaultProps,在以后的过程中,会再次调用,所以可以将控制控件状态的一些变量放在这里初始化,可以通过 this.state 来获取值,通过 this.setState 来修改。注意:一旦调用了this.setState方法,组件一定会调用render方法,对组件进行再次渲染

componentWillMount( ) :页面挂载前运行的函数

render( ):渲染模板的函数
视图层的DOM就在这里

componentDidMount( ):页面挂载完成时运行的函数
有关DOM的操作都放在此处执行,因为此时DOM才加载完。处理网络请求等加载数据的操作,一般都在此执行

组件数据更新的时候触发的函数

shouldComponentUpdate:判断是否要执行更新组件操作的函数
该函数自带两个参数,第一个参数为父组件传的值,第二个参数是更新后的值
此外还会return一个布尔值,false就不执行更新操作,不会加载下面的钩子。true就执行更新组件,并加载接下来更新组件的钩子
如果你不写这个函数,就默认为true
一般用于优化,可以返回false或true来控制是否进行渲染

componentWillUpdate( ):组件更新前运行的函数

render( ):每次更新数据,render都会运行重新渲染

componentDidUpdate( ):组件完成更新时运行的函数

改变父组件props传值的时候触发的函数

componentWillReceiveProps( )
该函数自带一个参数,为父组件的传值。
如果子组件使用父组件的传值,紧接着会触发组件数据更新时的钩子,也就是上面的4个函数

组件销毁的时候触发的函数

componentWillUnmount( )
一般在此清理定时器和监听器

demo练习:https://reactnative.cn/docs/sample-application-movies/

恭喜你,已经学完RN的基础,请在评论里面告诉我,有没有骗你,一天内就可以学完。

当你学到这时,你已经有能力写单页面了,接下来,你看我的超光速学习笔记二,学习组件间的跳转吧:https://blog.csdn.net/weixin_43943881/article/details/88561446

你可能感兴趣的:(React,Native,react,native,RN,ScrollView,Touchable,FlatList)