第5节:ReactNative的常用库

[TOC]

前言

一、安装指定版本

https://www.cnblogs.com/cisum/p/8401255.html

您可以通过指定依赖版本标签来指定要安装的软件包的版本

1
2
yarn add [package]@[version]
yarn add [package]@[tag]

[version][tag]将是什么被添加到您的package.json ,然后解决安装时依赖对。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
yarn add package-1@1.2.3
yarn add package-2@^1.0.0
yarn add package-3@beta

yarn add react-navigation

结果会是:
{
"dependencies": {
"package-1": "1.2.3",
"package-2": "^1.0.0",
"package-3": "beta"
}
}

link失败,怎么办

image-20191118221937663

诸如此类,其实是 react-native link react-native-gesture-handler 失败。

重复执行上述命令还是失败。怎么办?

答:直接手动remove掉RNGestureHandler.xcodeproj,然后再手动添加吧。

一、常用ReactNative库

查找地址:https://www.npmjs.com/package/

其他常用库文章:React Native插件系列之插件汇总

类型 Stat ⭐️
导航 react-navigation
及其Navigation prop reference(导航属性)
日历 react-native-calendars
Tab react-native-tab-navigator⭐️2187
日期计算 moment(github)⭐️41285
官网地址
地图 react-native-amap3d(github)⭐️690
图片浏览 react-native-image-viewer⭐️1361
轮播图 react-native-swiper⭐️7776
图片选择 react-native-image-picker⭐️5311
日期选择 react-native-datepicker ⭐️1585
进度显示 react-native-progress⭐️2358
Toast react-native-root-toast⭐️1191
网页

Picker相关

link方法:

二、导航(react-navigation)

官网文章:

参考文章:

  • 关于react-navigation 3.x的使用

    在安装3.x后,需要将最外层的包裹形式修改为createAppContainer

    在之前的版本中,使用createStackNavigator后,就会自动实现createAppContainer,但在新版本中,需要手动使用createAppContainer来包裹最外层的路由。

三、网页

使用

1
2
#import { WebView } from 'react-native';					# 被废弃的
import { WebView } from "react-native-webview"; # 现在使用的(附只支持 platform :ios, '9.0')

如果使用react-native中的WebView会提示如下警告:

react-native-webview

意思是webwiew要废了.不用了.

于是安装他们推荐的,用下面的命令
yarn add react-native-webview
react-native link react-native-webview

三、日期选择(react-native-datepicker)

1、安装及使用方法

官网地址:react-native-datepicker

1
npm install react-native-datepicker --save

2、主要参数说明

date:设置初始显示的日期
mode:显示的模式,date,datetime,time
format:设置日期格式,默认为’YYYY-MM-DD’
confirmBtnText:确定按钮的显示名称
cancelBtnText:取消按钮的显示名称
minDate:显示的最小日期
maxDate:显示的最大日期
duration:时间间隔
onDateChange:日期变化时触发的事件
placeholder:占位符

四、Antd库

1、各Antd库区别

类型 antd antd-mobile @ant-design/react-native
官网地址 https://ant.design/docs/react/introduce-cn https://mobile.ant.design/docs/react/introduce-cn https://rn.mobile.ant.design/docs/react/introduce-cn
安装命令 npm install antd –save npm install antd-mobile –save npm install @ant-design/react-native –save
特性和优势 UI 样式高度可配置,拓展性更强,轻松适应各类产品风格

2、RN-ANTD踩坑记

第3节:ReactNative的最基础知识

[TOC]

一、基础

1、Import与export

参考文章:ES6 export 和 export default的区别

1.1、知识储备

  • exportexport default的区别
导出方式 使用方式
export 用户必须需要知道所要加载的变量名,否则无法加载。
export default 但是用户肯定不愿意去阅读子组件看看导出名称叫啥,然后回来导入。所以就有了 export default。
  • {} 和 没{} 的区别

当import命令接受一对大括号,里面指定要从其他模块导入的变量名。大括号里面的变量名,必须与被导入模块对外接口的名称相同。

1.2、import使用示例

  • 当使用的是export,而不是export default的时候
1
2
3
4
5
// 使用方式1:常规方法
import { Greeting } from "./src/greeting";

//使用方式2:如果想为输入的变量重新取一个名字,import命令要使用as关键字,将输入的变量重命名
import { bieming as Greeting } from "./src/greeting";
  • 当使用的是export default的时候

可以用任意名称指向greeting.js输出的方法,这时就不需要知道原模块输出的变量名。

1
2
// 使用export default的时候可以有如下写法
import AnyName from "./src/greeting";

需要注意的是,这时import命令后面,不使用大括号。常见于export default createAppContainer(UIHomeNavigation);

2、颜色与图片资源

3、View样式属性

参考文章:

4、组件的属性添加及隐藏

需求距离:日期连接符,根据参数来判断是用直线还是波浪线。

定义:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
class DateConnectView extends React.Component {
constructor(props) {
super(props);
this.state = {
showWave: true
};
}

render() {
let dateConnectView = this.props.showWave ?
<View
style={{width: 20, height: 1, backgroundColor: "black"}}
/>
:
<View
style={{width: 20, height: 1, backgroundColor: "black"}}
/>


return (
<View>
{dateConnectView}
</View>

)
}
}

调用的时候:

1
<DateConnectView showWave={false} />

二、bind

ES5语法React.createClass会自动绑定this,ES6的写法,不再自动绑定this。

参考文章:

如果需要传参数,则采用箭头函数的写法。

三、常见问题

1、使用Class类出现的问题

1.1、View config not found for name完美解决方法

出现的原因是return的内容内组件的首字母不是大写,比如如果提示View config not found for name abc,则只需将abc换成Abc即可解决。

1.2、Only one default export allowed per module

export default class声明的类只能有一个,并且被引用的类要符合执行顺序

所以,请检查export default class 是不是太多了。

1.3、Module does not exist in the module map

Module does not exist in the module map 即
在Haste模块映射中或在这些映射中不存在,一般存在于对同一级目录的引用

1
2
3
import ButtonFactory from 'cjdemobuttonfactory'		// 错误
// 改为下面即可
import ButtonFactory from './cjdemobuttonfactory' // 正确

2、使用Text问题

2.1、Text文字的垂直居中

1
2
3
4
5
6
7
8
9
10
11
12
<Text style={{
flex: 1,
height: 44,
lineHeight:44, //添加这行即可使得Text文字垂直居中显示
textAlign: "center",
backgroundColor: "red",
color: '#5C5C5C',
fontSize: 15,
}}
>
"我是文字"
</Text>

3、使用列表 FlatList/SectionList 出现的问题

3.1、keyExtractor

VirtualizedList: missing keys for items, make sure to specify a key property on each item or provide a custom keyExtractor.

它警告我们每个item 要有不同的key 。默认情况下每行都需要提供一个不重复的key属性。你也可以提供一个keyExtractor函数来生成key。

1
2
3
4
5
6
7
8
9
10
<FlatList
keyExtractor={(item, index) => index.toString()} //不能缺少
/>

// keyExtractor也可以用方法写
keyExtractor = {this._extraUniqueKey}

_extraUniqueKey(item ,index){
return "index"+index+item;
}

3.2、virtualizedCell.cellKey

Warning: Failed child context type: Invalid child context virtualizedCell.cellKey of type number supplied to CellRenderer, expected string.

1
2
3
keyExtractor={(item, index) => index}						//会有警告⚠️
// 修改成如下:
keyExtractor={(item, index) => index.toString()}//成功

4、使用导航问题

TypeError: undefined is not an object (evaluating ‘this.props.navigation.navigate’)

检查下是不是导航栏不是在该类,而是在其他类上。常见于你在子组件中调用了该属性而发生错误。

举例:https://stackoverflow.com/questions/48446821/typeerror-undefined-is-not-an-object-evaluating-this-props-navigation-navigate

  • 问:怎么判断导航栏是否为空?
  • 答:

5、引用资源遇到的问题

Metro Bundler has encountered an internal error, please check your terminal error output for more details

可能原因:路径出错,如下:

1
2
3
icon:require('../image/home_n.png'),
//改成正确的路径后,问题解决
icon:require('./image/home_n.png'),

四、第三方库

1、添加库

1
2
3
4
cd xxx
npm install antd --save
npm install antd-mobile --save
npm install @ant-design/react-native --save

第1节:ReactNative详解布局

[TOC]

ReactNative详解布局

参考文章:

前言

布局

一、flex

flex:1 ,那么这是什么意思呢?
可以理解为比重

· 如果同级组件上只有一个,并且设置了 flex:1,那么这个组件相当于分配了全部空间。
· 如果同级组件上只有两个,并且这两个都设置了 flex:1,那么相当于这两个组件平均分配了全部空间。
· 如果同级组件上只有两个,并且第一个组件设置了 flex:1,第二个组件设置了 flex:2,那么相当于第一个组件占据全部空间的三分之一,第二个组件占据全部空间的三分之二。
· 如果没有设置 flex 属性,那么这个组件按需分配空间。

1、flex 与 width/height 的优先级

同时有flex、width、height时候,flex 与 width/height 的优先级

flex的优先级 > width/height。具体,

①、当组件是竖向排列时候,flex的优先级 > height,即height的设置会失效;

②、当组件是横向排列时候,flex的优先级 > width,即width的设置会失效;

如还有不懂此相关的文章可参考:https://www.jianshu.com/p/025f4ad7a4a4

二、flexDirection

flexDirection enum('row', 'column','row-reverse','column-reverse')
flexDirection属性定义了父视图中的子元素沿横轴或侧轴方片的排列方式。

类型 含义 图形举例
column(默认的排列方式) 从上向下排列
column-reverse 从下向上排列
row 从左向右依次排列
row-reverse 从右向左依次排列

图形举例:

image-20190522144243353

三、flexWrap

flexWrap enum('wrap', 'nowrap')
flexWrap属性定义了子元素在父视图内是否允许多行排列,默认为nowrap。

类型 含义
nowrap
(默认)
flex的元素只排列在一行上,可能导致溢出。
wrap flex的元素在一行排列不下时,就进行多行排列
wrap-reverse 换行,第一行在下方

图形举例:

image-20190522144822763

代码举例:

1
2
3
<View style={ {flexWrap:'wrap',flexDirection:'row',backgroundColor:"darkgray",marginTop:20}}>
···
</View>

四、justifyContent

类型 含义 row举例 column举例
flex-start
(default)
从行首开始排列。每行第一个弹性元素与行首对齐,同时所有后续的弹性元素与前一个对齐 image-20190522141651963 image-20190522141910412
center 伸缩元素向每行中点排列。每行第一个元素到行首的距离将与每行最后一个元素到行尾的距离相同。 image-20190522141712063 image-20190522141921712
flex-end 从行尾开始排列。每行最后一个弹性元素与行尾对齐,其他元素将与后一个对齐。 image-20190522141735033 image-20190522141945434
space-between 在每行上均匀分配弹性元素。相邻元素间距离相同。每行第一个元素与行首对齐,每行最后一个元素与行尾对齐。 image-20190522141408707 image-20190522141846812
space-around 在每行上均匀分配弹性元素。相邻元素间距离相同。每行第一个元素到行首的距离和每行最后一个元素到行尾的距离将会是相邻元素之间距离的一半。 image-20190522141755193 image-20190522142004059

其他图:

image-20190522143527522

代码使用举例:

1
2
3
<View        style={ {justifyContent:'center',flexDirection:'row',backgroundColor:"darkgray",marginTop:20}}>
···
</View>

五、alignItems(此样式设置在父元素上)

类型 比较 注意
justifyContent 决定其子元素沿着主轴排列方式
alignItems 决定其子元素沿着次轴排列方式

alignItems决定了子元素在次轴方向的排列方式(此样式设置在父元素上)。例如若子元素本来是沿着竖直方向排列的(即主轴竖直,次轴水平),则alignItems决定了它们在水平方向的排列方式。此样式和CSS中的align-items表现一致,默认值为stretch。

alignItems enum('flex-start', 'flex-end', 'center', 'stretch')
alignItems属性以与justify-content相同的方式在侧轴方向上将当前行上的弹性元素对齐,默认为stretch。

类型 含义
stretch
(默认)
弹性元素被在侧轴方向被拉伸到与容器相同的高度或宽度。
flex-start 元素向侧轴起点对齐
flex-end 元素向侧轴终点对齐
center 元素在侧轴居中。如果元素在侧轴上的高度高于其容器,那么在两个方向上溢出距离相同。

{justifyContent:'center',flexDirection:'row'}的情况下:

image-20190522151226308

六、alignSelf(此样式设置在子元素上)

类型 比较 注意
alignItems 决定了子元素在次轴方向的排列方式(此样式设置在父元素上
alignSelf 决定了该元素在父元素的次轴方向的排列方式(此样式设置在子元素上 其值会覆盖父元素的alignItems的值

七、其他

1、position(定位)

React Native 中,position 默认值为 relative,即相对布局。

position enum(‘absolute’, ‘relative’)属性设置元素的定位方式,为将要定位的元素定义定位规则。

类型 含义
relative
(默认值)
生成相对定位的元素,相对于其正常位置进行定位。因此,”left:20” 会向元素的 LEFT 位置添加 20 像素。
absolute 生成绝对定位的元素,元素的位置通过 “left”, “top”, “right” 以及 “bottom” 属性进行规定。

默认情况下,使用position: 'absolute'后,后面的元素会默认覆盖在前面的元素之上。

2、边缘与宽高(flex、width/height、top/left/bottom/right)

类型 含义
top 元素的上外边距边界与其包含块上边界之间的偏移
left 元素左外边距边界与其包含块左边界之间的偏移
bottom 元素的下外边距边界与其包含块下边界之间的偏移
right 元素右外边距边界与其包含块右边界之间的偏移
width 元素的宽
height 元素的高

①、相对布局relative下,flex优先级比width/height高

父组件的前提下 对子组件进行的设置 造成子组件结果
如果父组件设置了 flex 值 子组件设置了 flex 值的同时,也设置了高度值 则高度无效
如果父组件设置了 flex 值 子组件没有设置 flex 值,只设置了高度值, 则子组件高度有效

参考文章:React-Native 中的基本布局技巧

②、绝对布局absolute下,width/height优先级比flex高

3、margin(外边距)

类型 含义
marginTop 上外边距
marginLeft 左外边距
marginBottom 下外边距
marginRight 右外边距
marginHorizontal 左右外边距
marginVertical 上下外边距

4、padding(内边距)

类型 含义
paddingTop 上内边距
paddingLeft 左内边距
paddingBottom 下内边距
paddingRight 右内边距
paddingHorizontal 左右内边距
paddingVertical 上下内边距

5、视图边框

类型 含义
borderTopWidth 顶部边框宽度
borderLeftWidth 左边框宽度
borderBottomWidth 底部边框宽度
borderRightWidth 右边框宽度
borderColor 边框颜色
border<Bottom\ Left\ Right\ Top>Color 各个方向边框的颜色

第2节:ReactNative详解生命周期

[TOC]

跳转指定位置

ReactNative详解生命周期

前言

  • 1、数据变化怎么通知React(以按钮更新文本为例)

常用的通知React数据变化的方法是调用setState(data,callback),这个方法会合并data到this.state,并重新渲染组件。渲染完成后,调用可选的callback回调。大部分情况不需要提供callback,因为React会负责吧界面更新到最新状态。

详情查看:附一:StateEasyPage.js 与 StateNormalPage.js

  • 2、怎么给组件添加属性、设置默认值,并对默认值设置类型检查

一、了解state作用

1、this.setState({xxx:’’}) 与 this.state.xxx=’’

类型 this.state.xxx=’’ this.setState({xxx:’’})
作用 this.state通常是用来初始化state的 this.setstate是用来修改state值的
注意 再次调用时候,之前的state会被覆盖掉 再次调用时候,只会替换掉相应的state值

所以,自定义组件的时候,因为其需要传的参数是会被变化的,所以,我们在自定义组件中,不能使用state来更新,而是自定义组件中使用props,结合外部调用它的来处理。

2、认识state原理

2.1、this.setState({})

this.setState({})会触发render方法,重新渲染界面。而this.state.xxx=’’ 不会重新加载UI。

this.setState({})是异步的

三、类型判断

参考文章:

附一:StateEasyPage.js 与 StateNormalPage.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
//StateEasyPage.js
import React, { Component } from 'react';
import { View, Button, Text } from 'react-native';

export default class StateEasyPage extends Component {
constructor(props) {
super(props);
this.state = {
showText: "旧标题"
};
}

render() {
return (
<View>
<Button
title={"点击切换标题"}
onPress={()=>{
this.setState({
showText: "新标题"
})
}}
/>
<Text>{this.state.showText}</Text>
</View>
)
}
}

丰富一下,使其可以来回切换:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
//StateNormalPage.js
import React, { Component } from 'react';
import { View, Button, Text } from 'react-native';

export default class StateNormalPage extends Component {
constructor(props) {
super(props);
this.state = {
showText: "旧标题",
isShowNew: false
};
}

render() {
let currentShowText = this.state.isShowNew ? "新标题" : "旧标题"

return (
<View>
<Button
title={"点击切换标题"}
onPress={()=>{
let isShowNew = !this.state.isShowNew;
this.setState({
isShowNew: isShowNew
})
}}
/>
<Text>{currentShowText}</Text>
</View>
)
}
}

第2节:ReactNative使用技巧

[TOC]

ReactNative使用技巧

前言

一、布局

默认情况下,使用position: 'absolute'后,后面的元素会默认覆盖在前面的元素之上。

二、Text

1、[style]Android上Text默认的字体颜色,不是black,不是black,不是black

如果在Android上面,不显示地给Text添加color,那么显示出来的字体颜色就是灰色。跟iOS的表现不一致;
解决方案:
方案一:给每个Text都设置color

不足:每次都设置color。比较繁琐

方案二:写一个自定义组件

比如MyText,这个Text设置颜色,每次使用xxx就默认为你设置的颜色了。
不足:多出来了一个新的组件,也比较繁琐。
多出来了一个新的组件,也比较繁琐。

方案三:设置默认props

在入口文件里面写上默认的style,比如:
Text.defaultProps.sytle = { 'color': '#212121'}

第2节:ReactNative的继承重写等

[TOC]

ReactNative的继承重写等

参考文章:

1、问:怎么将页面的导航栏设置navigationOptions封装起来,使得子类可以只设置一个navigationOptions中的title值。
2、问:怎么在当前页面改变导航栏标题
3、怎么根据前一个页面的值动态更改导航栏标题

参考:

很多用React Native的同学都是前端工程师,在传统的js没有继承的概念。但是在react Native所支持的es6是有继承的,效果也是不错的。

第2节:ReactNative的继承重写等

[TOC]

ReactNative的继承重写等

参考文章:

1、问:怎么将页面的导航栏设置navigationOptions封装起来,使得子类可以只设置一个navigationOptions中的title值。
2、问:怎么在当前页面改变导航栏标题
3、怎么根据前一个页面的值动态更改导航栏标题

参考:

很多用React Native的同学都是前端工程师,在传统的js没有继承的概念。但是在react Native所支持的es6是有继承的,效果也是不错的。