一:props的约束性检查
ReactNative是一个弱类型的语言,类型检查做的非常差,编译的时候并不知道类型是什么,可能导致运行的时候出问题,比如我传入的是一个字符串,接收的可能是一个字符,编译的时候没有问题,运行的时候却会出问题。
props是一个传递的载体,是一个变量,这里面有许多属性,属性就必须要有一些类型。
props有一个技术,叫做类型约束检查
新建PropsTest文件
import React, {Component } from 'react';
import {Platform, StyleSheet, Text, View} from 'react-native';
import PropTypes from 'prop-types';
export default class PropsTest extends Component{
constructor(props) {
super(props);
}
//假设这个父组件没有把传进来,name默认叫做David
static defaultProps={
name:"David"
}
//类型检查,所有的类型检查的名字都必须写成propTypes
//isRequired表示必须传入的参数
static propTypes={
name:PropTypes.string,
age:PropTypes.number,
sex:PropTypes.string.isRequired,
}
//父组件向子组件传参数,子组件在进行类型检查
render() {
{/*
返回一个View,View里面传递姓名,年龄,性别
*/
}
return (<View>
{/*
render里面返回的是一个布局,布局里面不能出现裸变量,必须要有花括号{}包裹住
*/}
{/*
我们从props中取出name,刚开始的时候name肯定是不存在的,我们并
没有声明name,这个name是
从父组件传递进来的
*/}
<Text>姓名: {this.props.name}</Text>
<Text>age: {this.props.age}</Text>
<Text>sex: {this.props.sex}</Text>
</View>);
}
}
App.js文件进行修改
/**
* Sample React Native App
* https://github.com/facebook/react-native
*
* @format
* @flow
*/
import React, {Component} from 'react';
import {Platform, StyleSheet, Text, View} from 'react-native';
import PropsTest from './PropsTest'
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',
});
type Props = {};
export default class App extends Component<Props> {
render() {
return (
{/*
1,不仅要传参,还要做性能约束
2,字符串可以这么写name="river",数字类型必须加{}:age={11}
3,这里我们传入了三个参数,传到了PropsTypes这个组件的props变量里了
4,我们这里age需要传入数字类型,但是我们现在就算是传入字符串也不会报错,
该怎么办呢?我们可以 在接收的组件里进行类型检查
5,我们传的值无论是变量,还是函数,还是监听,都要写在标签里面,
使用空格隔开
*/}
<PropsTest name="river" age={11} sex="男"></PropsTest>
);
}
}
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,
},
});
看下运行效果
如果我们在 中,age传入字符串,在运行的话会出现这种问题
二ref详解
android中通过findViewById绑定控,React Native也需要绑定组件,这就是ref机制
。
通过在组件中加入ref=“某个字符串”,就可以定义一个组件的引用,类似于在android布局中xml标签的id属性
它有三种写法
1,第一种方式:我们新建RefTest.js文件
import React, {Component} from 'react';
import {Platform, StyleSheet, Text, View} from 'react-native';
import PropTypes from 'prop-types';
export default class RefTest extends Component {
constructor(props) {
super(props);
this.state={
size:100
}
}
//定义一个方法,方便在外界调用
getSize(){
//返回内部的state里面有一个变量叫size
return this.state.size;
}
render(): React.ReactNode {
return <Text>我叫陈商</Text>;
}
}
我们看下App.js文件,这是第一种写法
/**
* Sample React Native App
* https://github.com/facebook/react-native
*
* @format
* @flow
*/
import React, {Component} from 'react';
import {Platform, StyleSheet, Text, View} from 'react-native';
import RefTest from './RefTest'
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',
});
type Props = {};
export default class App extends Component<Props> {
constructor(props) {
super(props);
this.state={
size:0
}
}
render() {
return (
<View>
//stytle标签一定是有两个括号
//onpress为按钮事件,单击<Text/>的时候获取当前的组件
<Text style={{fontSize: 20}} onPress={()=>{
//1,声明一个变量去接收
//2,this.refs.refTest就相当于findViewById(),返回的是一个控件,
// 这个控件里有getSize();
var s=this.refs.refTest.getSize();
//给state赋值,这时size由0变为100
this.setState({size:s});
}}>
{this.state.size}
</Text>
<RefTest ref="refTest"></RefTest>
</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,
},
});
2,第二种方式
ref不在接收一个字符串,而是接收一个{}
我们修改下App.js文件
/**
* Sample React Native App
* https://github.com/facebook/react-native
*
* @format
* @flow
*/
import React, {Component} from 'react';
import {Platform, StyleSheet, Text, View} from 'react-native';
import RefTest from './RefTest'
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',
});
type Props = {};
export default class App extends Component<Props> {
constructor(props) {
super(props);
//创建refTest
this.refTest=React.createRef();
this.state={
size:0
}
}
render() {
return (
<View>
//stytle标签一定是有两个括号
//onpress为按钮事件,按钮的时候同事获取当前的组件
<Text style={{fontSize: 20}} onPress={()=>{
//这里直接
var s=this.refTest.getSize();
//给state赋值
this.setState({size:s});
}}>
{this.state.size}
</Text>
//1,这里的=>是一个回调函数,aaa是返回值因为return语句只有一句话,所以写成this.refTest=reftest
//2,当dom解析完成之后,ref就会回调该函数,并将值返回给refTest
<RefTest ref={aaa=>this.refTest=aaa}></RefTest>
</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,
},
});
运行效果与第一种方式一模一样
第三种方式与第一种方式类似,我这里就不演示了。
注意不能再构造方法中试图获取ref
三封装对象
React Native是一种面向对象性语言,那么如何声明一个类呢?就是使用class关键字
export default class Student{
constructor(name,sex,age) {
this.name=name;
this.sex=sex;
this.age=age;
}
getDescription(){
return "姓名: " + this.name + " 性别: " + this.sex + " 年龄 " + this.age;
}
}
四:导航栏
在android中实现导航栏可以使用切换界面,但是ReactNative将导航栏功能抽出来了,用于导航最知名的库是react-navigation,如果你要使用导航栏需在命令行中安装。
导航栏有三种导航形式:
Drawer Navigation,侧滑栏
Stack Navigation,
Tab Navigator
安装导航栏的命令
npm install --save react-navigation