添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

React Native 采用的是 ES2015 (即ES6)的语法标准,模板上使用了自己的 JSX 语法(在代码中嵌入结构标记)。

环境搭建

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 初始化项目
npm uninstall -g react-native-cli # 官方说不要用这个来初始化了,并且得卸载了,否则可能出现奇怪的问题
npx react-native init testProject --verbose # 新建项目目录,并初始化项目。命令会执行很久,且--verbose像没用似的,像卡死了一样
npx react-native init testProject --version 0.68.2 --verbose # 创建指定版本的项目
npx react-native init testProject --template react-native-template-typescript --verbose # 创建一个typescript的项目
npx react-native init testProject --template "[email protected].*" --verbose # 创建一个typescript的项目,指定版本

## 运行项目
cd testProject
npx react-native start
npx pod-install
npx react-native run-ios # 第一次启动会很慢。等模拟器运行起来后可以直接Cmd+R刷新应用,Cmd+D打开调试菜单
npx react-native run-ios --simulator='iPhone 13 Pro Max' # 指定云行的模拟器的名称
npx react-native run-android # 安卓开发最好安装上android studio,这不仅会帮你安装java、jdk,而且还能直接管理安卓模拟器,把android studio配置好了以后,android的开发环境也好了

npm install --save [email protected] # 直接指定版本号的更新升级,手动升级更爽。我不喜欢用react-native-git-upgrade来升级,需要注意的是,升级以后一定要顺便升级一下命令行工具react-native-cli,否则会可能会出现不预期的错误

prop&&state

两者可以说是大同小异,在大多数情况下,两者没什么很大的差别。两者的改变的时候,渲染的地方都会重新渲染。

prop : 一个组件的设置参数,可以理解为初始化参数或者对象的静态变量,并且可以在父组件中设置,在子组件中不可改变,但是可以一直往下传递至子子孙孙。

state : 更像是对象的一些变量,并且确实是经常改变的,只是父子之间不能传递。

1
2
3
4
// 动态设置某个状态值
this.setState({
results: value,
});

布局

不用css,但是类似css。所有的组件都有 style 属性。样式名是将默认的css的命名更改为了驼峰命名。一般使用 StyleSheet.create 在组件外面集中定义组件的样式。例如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// 指定固定的高度和宽度用width和height,React Native中的尺寸都是无单位的。
<View style={{width: 50, height: '50%', backgroundColor: 'powderblue'}} />

// 弹性的高度和宽度用flex。flex为1的时候表示撑满所有的剩余空间,如果多个并列子组件一起使用,则他们会平分空间,并且值越大所占比例就越大。例如
<View style={{flex: 2, backgroundColor: 'skyblue'}} />

<View style={[styles.css1, styles.css2]} /> // 包含多个样式

// 这样还能直接看出来层级关系。例如<Text style={styles.red}>test</Text>
const styles = StyleSheet.create({
bigblue: {
color: 'blue',
fontWeight: 'bold',
fontSize: 30,
},
red: {
color: 'red',
},
});

Flexbox布局

规定某个组件的子元素的布局。 flex 的值就类似于栅栏布局中的row宽度,一个2一个1,那么画面总共可以分成三份这种,如果直接 flex:1 ,那么就表示直接占据整个。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// 父视图属性
<View style={{
flex: 1,
flexDirection: 'row', // 规定布局方向,默认是column垂直方向布局,row表示水平方向布局
flexWrap:'wrap', // 默认为nowrap,表示子元素是否允许多行排列
justifyContent: 'flex-start', // 规定子元素沿着主轴的排列方式。可选项有flex-start、center、flex-end、space-around以及space-between
alignItems: 'stretch', //规定子元素沿着次轴(与主元素垂直的轴)的排列方式。可选项有flex-start、center、flex-end、stretch
}}>

// 子视图属性
<View style={{
alignSelf: 'auto', // 定义了flex容器内被选中项目的对齐方式可选auto, flex-start, flex-end, center, stretch
}}>

// flexGrow与flex有些类似,但是flex会使子元素的空间大小限定在父元素空间范围内,而flexGrow会使子元素起码维持其本身大小,再根据父元素是否有剩余空间进行空间分配。

居中问题

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// 图标悬浮与图片的正中间,两者均居中对齐
<View style={{
justifyContent: 'center',
alignItems: 'center',
}}>
<Icon name="microphone" size={70} style={{
position: 'absolute',
zIndex: 1,
justifyContent: 'center',
alignItems: 'center'
}}/>
<Image source={require('../img/test.png')} style={{
width: 250,
height: 250,
alignItems: 'center',
justifyContent:'center',
}}
/>
</View>

定位问题

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// 获取屏幕尺寸
import Dimensions from 'Dimensions';
Dimensions.get('window');

// 获取元素的位置: https://stackoverflow.com/questions/30096038/react-native-getting-the-position-of-an-element
class MyComponent extends React.Component {
render() {
return <View ref={view => { this.myComponent = view; }} />
}
componentDidMount() {
// Print component dimensions to console
this.myComponent.measure( (fx, fy, width, height, px, py) => {
console.log('Component width is: ' + width)
console.log('Component height is: ' + height)
console.log('X offset to frame: ' + fx)
console.log('Y offset to frame: ' + fy)
console.log('X offset to page: ' + px)
console.log('Y offset to page: ' + py)
})
}
}

组件

Animated动画

第三方库里面那些酷炫的效果均是通过动画来实现的

1
2
3
4
5
6
7
8
9
10
11
12
const top = useRef(new Animated.Value(100)).current;	// 将一个属性变为可以执行动画的属性

<Animated.View>
<View style={{top}}></View>
</Animated.View>

top.setValue(1000); // 当改变值的时候用setValue来执行,就能让改变变得平滑
Animated.timing(top, { // 也可以自定义执行时间
toValue: 1000,
duration: 500, // 默认500
delay: 100, // 默认为0
}).start()

Button基础按钮

这个组件的样式是固定的,如果需要自定义,那么高级的按钮参考 Touchable 系列

1
2
3
4
<Button
onPress={() => this._func()}
title="按钮标题必填"
/>

Image

图片组件,如果我们在同一个目录里面同时包含 a.png/[email protected],[email protected] 那么 react native 就能通过屏幕的分辨率自动选择不同尺寸的图片,并且在代码里面仅需要 require(./img/check.png) 就行了。

Navigation文档 ,Navigation已经单独成为一个模块,强烈建议不再使用老的导航器, 导航器对比 ,在这里有其更详细的文档。在 0.44 版本移除了 Navigator ,该模块被移动到 react-native-custom-components 现在也仅用于兼容老版本。使用前得先安装 npm install --save react-navigation 。有如下三种类型的导航器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# 看官网的意思就是要安装这些东西
npm install --save @react-navigation/native react-native-screens react-native-safe-area-context @react-navigation/native-stack

# ios需要执行
npx pod-install ios

# android需要再MainActivity中添加一个方法
import android.os.Bundle;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(null);
}

# 然后需要全局使用NavigationContainer包裹app,在app.js中
import * as React from 'react';
import { NavigationContainer } from '@react-navigation/native';

export default function App() {
return (
<NavigationContainer>{/* Rest of your app code */}</NavigationContainer>
);
}

StackNavigator

类似于普通的Navigator,体现在屏幕上方的导航栏

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
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
// StackNavigator用于创建多页面应用。其中每一个都是一个Component
import React from 'react';
import { View, Text } from 'react-native';
import { StackNavigator } from 'react-navigation';

class HomeScreen extends React.Component {
static navigationOptions = ({navigation}) => {return ()}; // 可以使用return的方法,这样可以在上面写一些逻辑
static navigationOptions = ({navigation}) => ({
title: '头部标题',
headerStyle: {
backgroundColor: '#ffffff', // 设置头部样式
},
headerTintColor: '#fff',
headerTitleStyle: { // 设置头部字体样式
fontWeight: 'bold'
},
headerRight: ( // 设置header bar的左右按钮
<Button
onPress={() => alert('This is a button!')}
title="Info"
color="#fff"
/>
),
// header头中直接进行页面跳转
headerRight: (<Button onPress={() => navigation.navigate('Setting')} title={'设置'} />),

});

componentWillMount() {} // render之前执行,并且永远只执行一次
render() {} // 渲染页面
componentDidMount() {} // 组件加载完成后执行,在render之后,已经有了DOM结构,不要把其他逻辑写在render,以防阻塞UI
componentWillReceiveProps() {} // 组件接收到一个新的prop时执行,这个方法在初始化render时不会被调用
shouldComponentUpdate() {} // 返回一个布尔值
componentWillUpdate() {} // 在组件接收到新的props或者state但还没有render时执行,初始化时不会执行
componentDidUpdate() {} // 组件更新完成后

render() {
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Text>Home Screen</Text>
</View>
);
}
}

// 可以在App.js中声明所有的页面,默认放在第一个的为首页
export default StackNavigator({
Home: {
screen: HomeScreen,
},
});

// 组件之间跳转方式
this.props.navigation.push('Home'); // 跳转至新的场景,并且将场景入栈
this.props.navigation.navigate('Home', {param1: '...'}) // 将新路由推送到堆栈导航器,如果它不在堆栈中,那么跳转到该页面
this.props.navigation.goBack()

TabNavigator

类似于ios的 TabBarController ,屏幕下方的标签栏

DrawerNavigator

侧边弹出的抽屉效果

SafeAreaView